2. The Kernel Source Tree

3. 配置内核
(1) 配置选择有Boolean和tristates两种类型.Boolean类型可以选择yes或no.内核特性,比如 CONFIG_PREEMPT通常就是Boolean型.tristates类型有yes,no,module3个值可选.设置成module表示编译成模块(可动态加载的对象).tristates类型的数据中,yes表示将代码编译到内核映像中,而不是一个模块.驱动通常就是tristates类型来配置的.
(2) 配置内核命令
文本模式下: $ make config
该命令会一个选项一个选项的让用户选择,会花很多时间.因此最好使用图形化的配置.
$ make menuconfig 或者基于gtk+的工具: $ make gconfig
$ make defconfig 该命令创建一个基于默认配置的配置.
$ make oldconfig 当更新了配置,或者使用了配置文件到新的内核代码中,使用该命令进行验证并更新配置.在编译内核之前需要运行该命令.
配置选项CONFIG_IKCONFIG_PROC能够将配置文件保存并压缩到 /proc/config.gz中.可以使用如下命令将备份的配置文件恢复进行新的编译.
$ zcat /proc/config.gz > .config
$ make oldconfig
内核配置完成后,使用make命令就可以编译内核了.
$ make
如果不想看到过多的编译信息,而只想看到警告和错误,可以使用如下命令重定向到其他文件:
$ make > ../detritus
还可以使用如下命令将无价值的输出信息重定向到null,也就是丢弃.
$ make > /dev/null
4.安装新内核
这取决于系统架构和Bootloader, 如果是x86使用grub引导,只需复制arch/i386/boot/bzImage目录到 /boot,更名为 vmlinuz-version之类的名字,然后编辑 /boot/grub/grub.conf,为新内核添加一个新的entry.对于Lilo,则编辑/etc/lilo.conf然后重新运行Lilo.
使用% make modules_install命令来安装内核模块,该命令将编译好的模块放到 /lib/modules下.
5.内核区别与用户程序的特点
(1) 内核不能访问C库和标准头文件
常用的C库函数有在内核中的实现,如printk()代替printf(),用法基本一样,唯一的区别是printk可以添加一个表示信息优先级的宏(注意没有逗号),如:
printk(KERN_ERR "this is an error!\n");
(2) 内核由GNU C编写
支持内联函数;内嵌汇编;likely()和unlikely()来优化分支语句.
(3) 内核缺少像用户空间一样的内存保护机制
(4) 内核很难进行浮点运算
(5) 内核的每个进程都只有固定的很小的栈空间
x86架构上一般为4KB或者8KB.32bit系统8KB,64bit系统16KB.
(6) 因为内核有异步中断,可抢占,支持SMP,同步和并发运行是内核需要重点注意的方面
通常的解决办法是使用自旋锁和信号量.
(7) 可移植性非常重要