技术开发 频道

Linux驱动开发必看:详解神秘内核

  2.1.5 Checking HLT instruction

  由于Linux内核支持多种硬件平台,启动代码会检查体系架构相关的bug。其中一项工作就是验证停机(HLT)指令。

  x86处理器的HLT指令会将CPU置入一种低功耗睡眠模式,直到下一次硬件中断发生之前维持不变。当内核想让CPU进入空闲状态时(查看arch/x86/kernel/process_32.c文件中定义的cpu_idle()函数),它会使用HLT指令。对于有问题的CPU而言,命令行参数no-hlt可以禁止HLT指令。如果no-hlt被设置,在空闲的时候,内核会进行忙等待而不是通过HLT给CPU降温。

  当init/main.c中的启动代码调用include/asm-your-arch/bugs.h中定义的check_bugs()时,会打印上述信息。

  2.1.6 NET: Registered protocol family 2

  Linux套接字(socket)层是用户空间应用程序访问各种网络协议的统一接口。每个协议通过include/linux/socket.h文件中定义的分配给它的少有的系列号注册。上述打印信息中的Family 2代表af_inet(互联网协议)。

  启动过程中另一个常见的注册协议系列是AF_NETLINK(Family 16)。网络链接套接字提供了用户进程和内核通信的方法。通过网络链接套接字可完成的功能还包括存取路由表和地址解析协议(ARP)表(include/linux/netlink.h文件给出了完整的用法列表)。对于此类任务而言,网络链接套接字比系统调用更合适,因为前者具有采用异步机制、更易于实现和可动态链接的优点。

  内核中经常使能的另一个协议系列是AF_Unix或Unix-domain套接字。X Windows等程序使用它们在同一个系统上进行进程间通信。

  2.1.7 Freeing initrd memory: 387k freed

  initrd是一种由引导装入程序加载的常驻内存的虚拟磁盘映像。在内核启动后,会将其挂载为初始根文件系统,这个初始根文件系统中存放着挂载实际根文件系统磁盘分区时所依赖的可动态连接的模块。由于内核可运行于各种各样的存储控制器硬件平台上,把所有可能的磁盘驱动程序都直接放进基本的内核映像中并不可行。你所使用的系统的存储设备的驱动程序被打包放入了initrd中,在内核启动后、实际的根文件系统被挂载之前,这些驱动程序才被加载。使用mkinitrd命令可以创建一个initrd映像。

  2.6内核提供了一种称为initramfs的新功能,它在几个方面较initrd更为优秀。后者模拟了一个磁盘(因而被称为initramdisk或initrd),会带来Linux块I/O子系统的开销(如缓冲);前者基本上如同一个被挂载的文件系统一样,由自身获取缓冲(因此被称作initramfs)。

  不同于initrd,基于页缓冲建立的initramfs如同页缓冲一样会动态地变大或缩小,从而减少了其内存消耗。另外,initrd要求你的内核映像包含initrd所使用的文件系统(例如,如果initrd为EXT2文件系统,内核必须包含EXT2驱动程序),然而initramfs不需要文件系统支持。再者,由于initramfs只是页缓冲之上的一小层,因此它的代码量很小。

  用户可以将初始根文件系统打包为一个cpio压缩包[1],并通过initrd=命令行参数传递给内核。当然,也可以在内核配置过程中通过INITRAMFS_SOURCE选项直接编译进内核。对于后一种方式而言,用户可以提供cpio压缩包的文件名或者包含initramfs的目录树。在启动过程中,内核会将文件解压缩为一个initramfs根文件系统,如果它找到了/init,它就会执行该顶层的程序。这种获取初始根文件系统的方法对于嵌入式系统而言特别有用,因为在嵌入式系统中系统资源非常宝贵。使用mkinitramfs可以创建一个initramfs映像,查看文档Documentation/filesystems/ramfs- rootfs-initramfs.txt可获得更多信息。

  在本例中,我们使用的是通过initrd=命令行参数向内核传递初始根文件系统cpio压缩包的方式。在将压缩包中的内容解压为根文件系统后,内核将释放该压缩包所占据的内存(本例中为387 KB)并打印上述信息。释放后的页面会被分发给内核中的其他部分以便被申请。

  在嵌入式系统开发过程中,initrd和initramfs有时候也可被用作嵌入式设备上实际的根文件系统。

  2.1.8 io scheduler anticipatory registered (default)

  I/O调度器的主要目标是通过减少磁盘的定位次数来增加系统的吞吐率。在磁盘定位过程中,磁头需要从当前的位置移动到感兴趣的目标位置,这会带来一定的延迟。2.6内核提供了4种不同的I/O调度器:Deadline、Anticipatory、Complete Fair Queuing以及NOOP。从上述内核打印信息可以看出,本例将Anticipatory 设置为了默认的I/O调度器。

0
相关文章