momo zone

调核人的blog

Monthly Archives: 十月 2010

搞定KDB

真是辛苦,这次搞定了KDB。 我是读完kernel的change log 后发现KDB 和 KGDB已经作为主线合并进了kernel >=2.6.35 差不多之前的编译配置方法都已经失效了,而且之前折腾的kernel <2.6.35基本都有BUG,不是键盘混乱就是死机。

1.4. KDB kernel debugger frontend

The Linux kernel has had a kernel debugger since 2.6.26, called Kgdb. But Kgdb is not the only linux kernel debugger, there is also KDB, developed years ago by SGI. The key difference between Kgdb and KDB is that using Kgdb requires an additional computer to run a gdb frontend, and you can do source level debugging. KDB, on the other hand, can be run on the local machine and can be used to inspect the system, but it doesn’t do source-level debugging. What is happening in this version is that Jason Wessel, from Windriver, has ported KDB to work on top of the Kgdb core, making possible to use both interfaces.

现在的状况是KDB和KGDB融合了,可以在KDB中进入KGDB(把KDB作为了KGDB的前端),或者在KGDB 中使用KDB的功能,不过总的来看是KDB融合进了KGDB而不是相反。这个进步可以看出内核调试器已经得到了承认。这里说一下KDB的编译条件:

  • CONFIG_DEBUG_RODATA is not set
  • CONFIG_DEBUG_SET_MODULE_RONX is not set
  • CONFIG_FRAME_POINTER=y
  • CONFIG_KGDB=y
  • CONFIG_KGDB_SERIAL_CONSOLE=y
  • CONFIG_KGDB_KDB=y
  • CONFIG_KDB_KEYBOARD=y

这里CONFIG_KGDB_SERIAL_CONSOLE最好编译进内核,原因后面说明。

KDB 的激活方式也完全改变了:

2.6.35以前是 echo 1 > /proc/sys/kernel/kdb 或 内核参数kdb=on

如果要在启动过程中较早进入kdb就需要把kgdboc模块编译进内核,然后加内核启动参数:kgdboc=kbd kgdbwait

2.6.35之后是echo kbd > /sys/module/kgdboc/parameters/kgdboc 没错名字叫kgdboc 就是编译的时候的配置CONFIG_KGDB_SERIAL_CONSOLE的产物,如果编译成了模块是不会自动加载的,需要modprob kgdboc才能看到这个文件。所以还是编译到内核罢了。

另外还可以echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc 启动串口上的调试,这就是kgdb,kdb融合的产物。

然后进入KDB 方式也更改了:

2.6.35 之前是直接按pasue

2.6.35 之后是sysrq + g ,或者echo g > /proc/sysrq-trigger

进入KGDB方式:

gdb vmlinux-kgdb

(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0

ok ,这样就可以了,试了半天一切正常,单步执行和继续执行都没有死机,我还开着X ,用着wifi ,比以前稳定得多。

但是KDB好像会使bash进入D进程状态,系统无法响应。继续等官方打补丁。

这里有几个重要的参照:

http://kernelnewbies.org/Linux_2_6_35

https://kgdb.wiki.kernel.org/index.php/Main_Page

https://kgdb.wiki.kernel.org/index.php/KDB_FAQ

http://kernel.org/pub/linux/kernel/people/jwessel/kdb/kgdbKernelArgs.html

X window的书

我发现关于Xwindow的书都差不多像圣经古卷那般被藏在一个角落或大柜子中,根本不会出现在大街小巷。我查遍google 也就发现这么几本,而且还是扫描的pdf ,就像从博物馆里扒出来的一样,当然没有完整的下载。

1.这个是最猛的,估计要出新书也就抄抄这些本子吧

《Definitive Guides to the X Window System》丛书

Book Cover: Motif Programming Manual (The Definitive Guides to the X Window System, Volume 6

一共9卷
《Volume 0:X Protocol Reference Manual》
《Volume 1:Xlib Programming Manual》
《Volume 2:Xlib Reference Manual》
《Volume 3M:X Window System User’s Guide》
《Volume 4M:X Toolkit Intrinsics Programming Manual》
《Volume 5:X Toolkit Intrinsics Reference Manual》
《Volume 6A:Motif Programming Manual》
《Volume 7A:XView Programming Manual》
《Volume 8:X Window System Administrator’s Guide》
O’reilly公司出版 www.oreilly.com
封面是一个大大的X , 很震撼很晦涩,很上不了台面…..
2.X Window 超級工具
中文的,不知道原书是什么,为数不多的中文资料。

3.X Window 彻底研究/旗标系列图书

人民邮电出版社, 2000 – 547 页
这本应该是抄的,不过如果翻译的好也能看,关键是连个预览都没有只能在这里先记一下了。
4.The joy of X: an overview of the X Window system
封面很逗,宗教风格,再次印证了Xwindow 是个彻底和普通开发者无关的东西。

Vmalloc 范围

Vmalloc可以获得的地址在VMALLOC_START到VMALLOC_END的范围中。这两个符号在<asm/pgtable.h>中定义:

/* include/asm/pgtable.h */

#define VMALLOC_OFFSET               (8*1024*1024)

#define VMALLOC_START                 (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))

…………

high_memory值在这里定义:

/* arch/arm/mm/init.c */

void __init bootmem_init(struct meminfo *mi)

{

……

high_memory = __va(memend_pfn << PAGE_SHIFT);

}

在我们的板子上,这些值为:

high_mem = 0xc4000000                  <———    3G+64M  , high_memory既实际内存最大物理地址对应的的内核逻辑地址

VMALLOC_START = 0xc4800000     <———    3G+64M+8M  (8M为内核规定的一个gap) ,vmalloc分配的起始地址(内核空间)

我在kernel里加了一些打印信息,打印出的结果如下:

Starting kernel …

Linux version 2.6.18_pro500-omap5912_osk (root@ubuntu) (gcc version 4.2.0 20070319 (prerelease) (MontaVista 4.2.0-4.0.0.0702865 2007-03-26)) #36 Mon Jun 16 16:29:30 CST 2008

CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177

Machine:

Memory policy: ECC disabled, Data cache writeback

high_mem = 0xc4000000 ——————–

vmalloc_start = 0xc4800000 ———————-

…………

The following is the vmalloc test processing:

/* Vmalloc Test Module */

……

static int __init tcm_init(void)

{

struct resource * ret;

unsigned long * vaddr1 = NULL;

unsigned long * vaddr2 = NULL;

……

vaddr1 = vmalloc ( PAGE_SIZE );

printk(“vaddr1  = 0x%p \n”, vaddr1);

vaddr2 = vmalloc ( PAGE_SIZE );

printk(“vaddr2  = 0x%p \n”, vaddr2);

vfree(vaddr1);

vfree(vaddr2);

……

}

……

module_init(tcm_init);

module_exit(tcm_exit);

The running result:

# insmod tcm1.ko

vaddr1  = 0xc487a000      ß vmalloc分配的地址,大于0xc3ffffff (3G+64M)

vaddr2  = 0xc487c000

参考资料: (摘自《Linux 内存管理》)

vmalloc分配的内核虚拟内存与kmalloc/get_free_page分配的内核虚拟内存位于不同的区间,不会重叠。因为内核虚拟空间被分区管理,各司其职。进程空间地址分布从0到3G(其实是到PAGE_OFFSET, 在0x86中它等于0xC0000000),从3G到vmalloc_start这段地址是物理内存映射区域(该区域中包含了内核镜像、物理页面表mem_map等等)比如我使用的系统内存是64M(可以用free看到),那么(3G——3G+64M)这片内存就应该映射到物理内存,而vmalloc_start位置应在3G+64M附近(说”附近”因为是在物理内存映射区与vmalloc_start期间还会存在一个8M大小的gap来防止跃界),vmalloc_end的位置接近4G(说”接近”是因为最

后位置系统会保留一片128k大小的区域用于专用页面映射,还有可能会有高端内存映射区,这些都是细节,这里我们不做纠缠)。

get_free_page或Kmalloc函数所分配的连续内存都陷于物理映射区域,所以它们返回的内核虚拟地址和实际物理地址仅仅是相差一个偏移量(PAGE_OFFSET),你可以很方便的将其转化为物理内存地址,同时内核也提供了virt_to_phys()函数将内核虚拟空间中的物理映射区地址转化为物理地址。要知道,物理内存映射区中的地址与内核页表是有序对应的,系统中的每个物理页面都可以找到它对应的内核虚拟地址(在物理内存映射区中的)。

vmalloc分配的地址则限于vmalloc_start与vmalloc_end之间。每一块vmalloc分配的内核虚拟内存都对应一个vm_struct结构体(可别和vm_area_struct搞混,那可是进程虚拟内存区域的结构),不同的内核虚拟地址被4k大小的空闲区间隔,以防止越界——见下图)。与进程虚拟地址的特性一样,这些虚拟地址与物理内存没有简单的位移关系,必须通过内核页表才可转换为物理地址或物理页。它们有可能尚未被映射,在发生缺页时才真正分配物理页面。


为什么32bit kernel要把896MB以上物理内存定义为高端内存

为什么内核把高端内存的分界设置在物理内存的896MB处??这个问题确实很令人迷惑。接下来一步步思考来搞明白它:

1. 首先32bit 系统最大物理寻址范围4GB ,这个地球人都知道。但是在操作系统支持的保护模式下这个4GB是虚拟地址。你问我为啥??难道不记得X86中的cr3寄存器(用来放页目录基址),也就是说内核发出的任何地址都需要cpu解码成物理地址,当然这个是硬件完成的。

2. 如果上面的还好理解那么下面的只有了解内核结构的底层开发者才好理解。

linux的设计者需要一个多进程多任务的os,并希望这4GB虚拟地址空间能够充分利用,那么就对虚拟内存作了一个简单的分割:0-3GB 给ring3 用作用户进程空间,3-4GB给ring0 用作内核空间。而内核空间中除了内核镜像(当然它也在物理空间中)其余就都给去映射物理空间了。对于物理内存,内核在设计时,实际可以直接访问的物理内存就最大只有1GB(原因:内核固定页表数限制)。注意内核和用户程序有不同的页目录和页表,前者不能变更,后者可以随意变更。

3.后来PC的物理内存突破了1GB,这可让linux的设计者挠破了头,因为内核就是基于最大1GB物理内存设计的。linux的设计者必须再设计一个额外的机制来支持1GB以上内存的访问,并能够兼容旧的小于1GB内存的系统。最终解决办法是把1GB的内核空间内再划分出128MB用来映射(可变映射)高于1GB的物理内存。这128MB映射区最大只能映射高端内存中某个区域的128MB空间。 如果要映射高端内存中的另外一段空间,就要先取消映射,再建立映射,相当繁琐。最后kernel的内核空间布局就这样了:划出128MB意味着内核空间的固定映射区缩小为896MB,也就是说896MB以上的内存都不能直接访问了(不在内核固定映射区)。

4.最后还有重要的一点,就是896MB以上高端内存仅仅是针对内核程序而言,用户程序有自己的页表,完全可以修改并直接映射到任意物理地址

关于scullv 的一些疑问

差不多关于设备文件中内存分配的问题就剩scullv了,这是最后一个。 在调试scullv时最大的一个问题是如果需要空间过大kernel 会报oops : dd if=~/pkg/VirtualBox-3.1-3.1.4_57640_openSUSE111-1.i586.rpm of=/dev/scullv0 Killed message:

Oct 23 22:49:09 linux-hm12 kernel: [15768.684678] BUG: unable to handle kernel paging request at f849e000
Oct 23 22:49:09 linux-hm12 kernel: [15768.684684] IP: [<c065cd1d>] iret_exc+0x7c1/0xa2d
Oct 23 22:49:09 linux-hm12 kernel: [15768.684693] *pdpt = 00000000009b7001 *pde = 0000000035bfa067 *pte = 0000000000000000
Oct 23 22:49:09 linux-hm12 kernel: [15768.684700] Oops: 0002 [#7] PREEMPT SMP
Oct 23 22:49:09 linux-hm12 kernel: [15768.684705] last sysfs file: /sys/devices/virtual/net/vboxnet0/statistics/collisions
Oct 23 22:49:09 linux-hm12 kernel: [15768.684710] Modules linked in: scullv scullc joydev st lp parport_pc ppdev parport af_packet binfmt_misc snd_pcm_oss snd_mixer_oss snd_seq w83627ehf hwmon_vid snd_seq_device coretemp vboxnetadp vboxnetflt vboxdrv mperf fuse loop dm_mod radeon ttm drm_kms_helper drm iwlagn firewire_ohci firewire_core arc4 ecb iwlcore rtl8187 snd_hda_codec_analog crc_itu_t 8139too ohci1394 skge 8139cp ieee1394 mac80211 snd_hda_intel snd_hda_codec eeprom_93cx6 iTCO_wdt snd_hwdep button pcspkr iTCO_vendor_support i2c_i801 snd_pcm sky2 snd_timer cfg80211 snd tpm_tis soundcore snd_page_alloc i2c_algo_bit tpm tpm_bios sr_mod cdrom rfkill intel_agp sg floppy edd reiserfs fan ata_generic thermal processor thermal_sys pata_jmicron [last unloaded: scullv]
Oct 23 22:49:09 linux-hm12 kernel: [15768.684775]
Oct 23 22:49:09 linux-hm12 kernel: [15768.684779] Pid: 10886, comm: dd Tainted: G      D     2.6.35.1-1-desktop #2 P5B-Deluxe/System Product Name
Oct 23 22:49:09 linux-hm12 kernel: [15768.684785] EIP: 0060:[<c065cd1d>] EFLAGS: 00010246 CPU: 1
Oct 23 22:49:09 linux-hm12 kernel: [15768.684789] EIP is at iret_exc+0x7c1/0xa2d
Oct 23 22:49:09 linux-hm12 kernel: [15768.684794] EAX: 00000000 EBX: 00000200 ECX: 00000200 EDX: 08059000
Oct 23 22:49:09 linux-hm12 kernel: [15768.684798] ESI: 08059000 EDI: f849e000 EBP: 00000000 ESP: c3bb7f20
Oct 23 22:49:09 linux-hm12 kernel: [15768.684802]  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Oct 23 22:49:09 linux-hm12 kernel: [15768.684807] Process dd (pid: 10886, ti=c3bb6000 task=cdb5d8d0 task.ti=c3bb6000)
Oct 23 22:49:09 linux-hm12 kernel: [15768.684811] Stack:
Oct 23 22:49:09 linux-hm12 kernel: [15768.684814]  f849e000 00000200 ce01e000 00000200 ce01e018 fffffff2 f848c644 f848cde8
Oct 23 22:49:09 linux-hm12 kernel: [15768.684820] <0> 00000001 f244b458 c03b07ac 00001000 ef1bc3dc 00000000 00000200 08059000
Oct 23 22:49:09 linux-hm12 kernel: [15768.684828] <0> f24aeb80 cdad9100 00000200 08059000 f848c550 c0315fd0 c3bb7f9c 00000000
Oct 23 22:49:09 linux-hm12 kernel: [15768.684837] Call Trace:
Oct 23 22:49:09 linux-hm12 kernel: [15768.685127] Inexact backtrace:
Oct 23 22:49:09 linux-hm12 kernel: [15768.685127]
Oct 23 22:49:09 linux-hm12 kernel: [15768.685127]  [<f848c644>] ? scullv_write+0xf4/0x210 [scullv]
Oct 23 22:49:09 linux-hm12 kernel: [15768.685127]  [<c03b07ac>] ? security_file_permission+0xc/0x10
Oct 23 22:49:09 linux-hm12 kernel: [15768.685127]  [<f848c550>] ? scullv_write+0x0/0x210 [scullv]
Oct 23 22:49:09 linux-hm12 kernel: [15768.685127]  [<c0315fd0>] ? vfs_write+0xa0/0x190
Oct 23 22:49:10 linux-hm12 kernel: [15768.685127]  [<c0316a41>] ? sys_write+0x41/0x70
Oct 23 22:49:10 linux-hm12 kernel: [15768.685127]  [<c020318c>] ? sysenter_do_call+0x12/0x22
Oct 23 22:49:10 linux-hm12 kernel: [15768.685127] Code: e9 89 3c da ff 8d 0c 88 e9 3b 3d da ff 8d 0c 8b e9 73 3d da ff ba f2 ff ff ff e9 b9 3d da ff 01 e9 eb 04 8d 4c 8d 00 51 50 31 c0 <f3> aa 58 59 e9 56 3e da ff 8d 0c 88 51 50 31 c0 f3 aa 58 59 e9
Oct 23 22:49:10 linux-hm12 kernel: [15768.685127] EIP: [<c065cd1d>] iret_exc+0x7c1/0xa2d SS:ESP 0068:c3bb7f20
Oct 23 22:49:10 linux-hm12 kernel: [15768.685127] CR2: 00000000f849e000
Oct 23 22:49:10 linux-hm12 kernel: [15768.685127] —[ end trace ce27dbec989e1449 ]—
出现这个问题主要是因为高端内存空间不足:
localhost:~/ldd3/scullc # cat /proc/meminfo |grep Free
MemFree:          130180 kB
HighFree:          17696 kB #高端物理内存的剩余空间
LowFree:          112484 kB
SwapFree:        1052188 kB
HugePages_Free:        0
VmallocTotal:     122880 kB
VmallocUsed:       66956 kB #vmalloc 映射区占用
VmallocChunk:      36584 kB
默认的内核配置是仅仅分配少于128MB空间(Vmalloc_area)供物理高端内存(HIGH_MEM)映射,而这个内存映射区是在虚拟空间中的内核部分(1GB),所以这个高端内存映射区大小也是有限的。加内核参数可以更改这个Vmalloc_area的大小: vmalloc=256M .
这里说一下如何根据oops追踪代码:
看到[<f848c644>] ? scullv_write+0xf4/0x210 [scullv] 这样的就应该知道出错的指令在0xf4 然后用objdump -d -S scullv.ko > scullv.S 反编译+C源码对照很容易就定位出错位置。

新买的Acer 7741G

因为要买17寸的,所以没怎么没挑直接奔Acer 拿下7741G 。后来发现这个性价比真是超高!

I3-370M , 2GB DDR3,HD5650 ,500G HIT ,LG ODD,Atheros 11N

最后看到3项配置可以感觉到这个机器不是糊弄小白的。HIT的硬盘仍然是本子上最稳定的盘,LG的ODD仍然是很耐用的, Atheros 11N卡不用说了,比broadcom 好多了。第一次用带超线程的,用rar测试了一下并没有感觉很快。

这里重点说一下显卡。 这个HD5650 真的是太强了,用在笔记本上真是再合适不过了。这个卡的参数很强大不用说,比台机上的hd5770 1GB差点, 另外我第一次在这个卡上启用了硬解高清,cpu利用率下降到0%~10% 。画质没有变化,但感觉比i3软解流畅一些。

硬解毫无压力:

SF4 最高画质,4XAA , 同样无压力 60F/s

苍翼默示录  , LED的效果很好。

再一次KDB,依然杯具

实在不能让人安心,再搞一下KDB 吧。目前的状况是可以进入kdb ,不死机了。但键盘全部乱掉了,无法继续操作。google到这样一个线索,tty1-tty6 是虚拟终端,只有F10下的console才是真正的终端。而虚拟终端的设备驱动可能导致kdb响应错误。我赶紧试了一下,确实是这样。但是在断点后执行go或ss仍然出错。而且无法从kdb返回(显示一堆错误) 。这个可能和键盘驱动或内核补丁有关(用的不是“纯净版”的内核)。用single模式 以及kdb=early 参数都不正常。这个有空再搞吧。

关于intel wifi link 1000

关于intel的新卡wl1000 ,看到这个数字对比5XX0 和6XX0 ,可以想象应该是个低端卡,查了一下intel的资料果然是这样,不过缩水之后功耗是降低了。不过总的来说intel的卡功耗比螃蟹卡好多了,螃蟹卡的温度那叫蒸螃蟹啊。

一、Intel WiFi Link 1000、5100/5300真正的参数,数据来自Intel官网:

Intel Wi-Fi Link 频段 标准 MIMO规格 速率(Mbps) 天线接口个数 体积
1000 单频(2.4G) IEEE 802.11b/g/n 1×2 300 2 全高半高
5100 双频(5.4G/2.4G) IEEE 802.11a/b/g/n 1×2 300 2 全高半高
5300 双频(5.4G/2.4G) IEEE 802.11a/b/g/n 3×3 450 3 全高

二、网上流传的说1000是“1×1 MIMO”说法是错误的,说1000是“上传单任务”法的也是错的,说它“是5100的精简版”也是错误的!一方面错在提出这个说法的网友没看仔细或英语水平不行,翻译错了,二是即使说它是1×1的,那规范的说法也应是“1×1 SISO(单进单出)”!严格来说1×2应是“SIMO(单进多出)”;三是无论在上传还是下载在IEEE802.11n标准下速度与5100是一样的!四是即使要说1000精简了,也不是在MIMO上,而是在频段上!

三、对Intel WiFi Link 1000的评价:
1.Intel WiFi Link 1000是Intel新推出的为了适应上网本和轻薄本而推出的,与ATOM、CULV平台相适应的新一代网卡,采用了新的制造工艺,有着节能省电、发热量低、体积小巧和重量轻的特点!
2.1000与5100一样,同是1×2 MIMO规格,在IEEE 802.11n规范中提供与5100一样的300Mbps速率,同样板载两个天线物理接口!
3.1000比5000系列省了目前已经淘汰了的5.2G频段,不支持IEEE 802.11a标准!这算是升级还是精简,看各位自己怎么看了!而在我看来,1000与5000系列没有精简升级的关系,应说1000是个全新定位,全新的系列,放弃对802.11a支持是为了更好的降低功耗,适应节能减排这一时代主题,是真正IEEE 802.11n时代的无线网卡!不然,Intel不会把它命名为“Intel Centrino Wireless-N 1000”,而会命名为“5100 BGN”(比5100少了A)……

关于2.4GHz的wifi频道划分

找到一个2.4Ghz 范围内各信道的分布图,这个有什么用?想要获得高连接质量的人都明白~~

这个一眼就看出来其实真正独立的频道只有1,6,11。

关于scullp 调试过程的一些领悟

scullp 可以说比scullc更底层的一个函数。而之前的scull的kmalloc是基于slab的所以从高到低的顺序是scull>scullc>scullp 这样看来应该是scullp的开销最小。ok测试一下吧 :

localhost:~/ldd3/scullc # time dd if=/media/0-2-0-FILES/3rd_trailer_03_hd.mp4   of=/dev/scullc  bs=1GB count=1
0+1 records in
0+1 records out
408014642 bytes (408 MB) copied, 0.56488 s, 722 MB/s
real    0m0.602s
user    0m0.006s
sys     0m0.594s
localhost:~/ldd3/scullp # time dd if=/media/0-2-0-FILES/3rd_trailer_03_hd.mp4 of=/dev/scullp bs=1GB count=1
0+1 records in
0+1 records out
408014642 bytes (408 MB) copied, 0.576057 s, 708 MB/s
real    0m0.614s
user    0m0.009s
sys     0m0.601s

这个结果很意外啊 ,好像差不多,貌似还差点。 继续看了一下源码,主要order这个设备中的成员,order和需要连续申请的页数有关(log2N) 。可以想象如果order变得大了,那么就需要更多连续空闲页。那么内核就会执行更简化的代码,开销也会变小。那么动手试一下吧,把order 改成11,2048个页=8MB

localhost:~/ldd3/scullp # time dd if=/media/0-2-0-FILES/3rd_trailer_03_hd.mp4 of=/dev/scullp bs=1GB count=1
dd: writing `/dev/scullp’: Cannot allocate memory
0+1 records in
0+0 records out
0 bytes (0 B) copied, 0.317467 s, 0.0 kB/s
real    0m0.341s
user    0m0.000s
sys     0m0.340s

看来不行了,说明在给408MB 分配空间的过程中至少有一次不能分配到连续8MB的空闲页。 在把order改成5, 什么死机了!! 再试一下,又死了!!这个程序有bug? 再把order改成8看看。

localhost:~/ldd3/scullp # time dd if=/media/0-2-0-FILES/3rd_trailer_03_hd.mp4 of=/dev/scullp bs=1GB count=1
0+1 records in
0+1 records out
408014642 bytes (408 MB) copied, 0.507563 s, 804 MB/s
real    0m0.530s
user    0m0.000s
sys     0m0.529s
localhost:~/ldd3/scullp # time dd if=/media/0-2-0-FILES/3rd_trailer_03_hd.mp4 of=/dev/scullp bs=1GB count=1
0+1 records in
0+1 records out
408014642 bytes (408 MB) copied, 0.508213 s, 803 MB/s
real    0m0.532s
user    0m0.001s
sys     0m0.530s
下面是scullc
localhost:~/ldd3/scullc # time dd if=/media/0-2-0-FILES/3rd_trailer_03_hd.mp4 of=/dev/scullc bs=1GB count=1
0+1 records in
0+1 records out
408014642 bytes (408 MB) copied, 0.56219 s, 726 MB/s
real    0m0.600s
user    0m0.006s
sys     0m0.594s
localhost:~/ldd3/scullc # time dd if=/media/0-2-0-FILES/3rd_trailer_03_hd.mp4 of=/dev/scullc bs=1GB count=1
0+1 records in
0+1 records out
408014642 bytes (408 MB) copied, 0.561283 s, 727 MB/s
real    0m0.599s
user    0m0.010s
sys     0m0.588s

确实有微弱优势。但scullp在order大的情况下分配失败的可能性很大。而order小了优势不明显。

如果真的要从实用和易用的角度看还是直接用kmalloc 就够了