Compiling Linux-Kernel
README
- 作者:邢万里
- 学校:重庆邮电大学
- email:wlxing@yahoo.com
- 基于ubuntu12.04(原内核3.13.0 - 32 - generic)
- 新内核3.3.8,eCryptfs模块
内核编译
前期准备(menuconfig)
基本知识
下文摘抄wiki-menuconfig官网
基本命令(内核源码README详解)
(1)sudo make dep:(2.6前)建立目标文件的依赖关系;读取配置过程生成的配置文件,来创建对应于配置的依赖关系树。
(2)sudo make clean:(2.6前)删除文件中的依赖关系(有dep产生的)。
(3)sudo make mrproper:(2.6前后)删除包括.config在内的生成的目标文件
(4)sudo make config
(5)sudo make xconfig
(6)sudo make gconfig
(7)sudo make oldconfig:基于已有的.config进行配置, 若有新的符号, 它将询问用户。
(8)sudo make defconfig: 按默认选项对内核进行配置(386的默认配置是Linus做的)。
(9)sudo make menuconfig:图形界面设置.config(后文以此方法描述)。
(10)sudo make bzImage:(2.6前)编译(还有一个make modules)
(11)sudo make:(2.6后)创建一个压缩的内核镜像。相当于2.6前的make (b)zImage + make modules。
(12)sudo make modules:(2.6前)生成相应的模块。
(13)sudo make modules_install:(2.6前后)如果你在config设置了模块,则必须使用这一步:安装模块。把模块拷贝到需要的目录中(一般是/lib/modules/)。
(14)sudo make install:(2.6后)
(15)sudo mkinitramfs 3.13.3 -o/boot/initrd.img-3.13.3
(16)sudo update-initramfs -c -k 3.13.3
(17)sudo update-grub2基本文件
(1)initrd.img:
initrd.img是一个小的映象,包含一个最小的linux系统。通常的步骤是先启动内核,然后内核挂载initrd.img,并执行里面的脚本来进一步挂载各种各样的模块,然后发现真正的root分区,挂载并执行/sbin/init等等。kernel2.5是一条分界线。
(2)vmlinux:
vmlinux是未压缩的内核,“vm”代表“Virtual Memory”。vmlinux 是ELF文件,即编译出来的最原始的文件。
(3)vmlinuz:
是可引导的、压缩的内核。vmlinuz是vmlinux的压缩文件。vmlinuz是一个统称,有两种具体的表现形式:zImage和bzImage(big zImage)。
(4)system.map
System.map文件用于存放内核符号表信息。符号表是所有内核符号及其对应地址的一个列表,随着每次内核的编译,就会产生一个新的对应System.map文件,当内核运行出错时,通过System.map中的符号表解析,就可以查到一个地址值对应的变量名。
(5)zImage:
vmlinuz经过gzip压缩后的文件,适用于小内核。
(6)bzImage:
vmlinuz经过gzip压缩后的文件,适用于大内核。zImage和bzImage的区别在于本身的大小和加载到内存的地址不同。zImage是0~640KB,bzImage是1M以上。如果内核比较小,那么可以采用zImage 或bzImage之一,两种方式引导的系统运行时是相同的。大的内核采用bzImage,不能采用zImage。
(7)/lib/modules
该目录包含了内核模块及其他文件. 注意, modules中一般会有多个目录: 系统自带的内核模块在这里, 你编译自己的内核模块后, 它们也会被安装到这里. 不同的目录由内核版本号来区分. 即modules里目录的名称是内核版本号. (使用$ uname -r 可知当前系统内核所用的模块位于哪个目录).
(8)/lib/modules//build
储存为该版本的内核编译新模块所需的文件. 包括Makefile, .config, module.symVers(模块符号信息), 内核头文件(位于include/, include/asm/中)
(9)/lib/modules//kernel
储存内核目标文件(以.ko为后缀). 它的目录组织和内核源代码中kernel的目录组织相同.
(10)/lib/modules//中:
modules.alias : 模块别名定义. 模块加载工具使用它来加载相应的模块.
modules.dep : 定义了模块间的依赖关系.
modules.symbols : 指定符号属于哪个模块.编译流程变化(kernel2.6前后,见附录A)
(1)自2.6内核开始,就不用make dep了,依赖关系会自动维护,并且命令也减少了,以往是:
//2.6之前
sudo make dep
sudo make clean
sudo make bzImage/sudo make zImage
sudo make modules
sudo make modules_install
拷贝.../linux/arch/i386/boot/bzImage到/boot下。
**************************
//2.6之后
sudo make
sudo make modules_install
sudo make install(自动更新grub等其他文件)
编译流程
#sudo apt-get install build-essential kernel-package libncurses5-dev libqt3-headers
安装所需要的工具。
build-essential (基本的编程库(gcc, make等)
kernel-package (Debian 系统里生成 kernel-image 的一些配置文件和工具)
libncurses5-dev (meke menuconfig要调用的)
libqt3-headers (make xconfig要调用的)下载请到此内核源码镜像处寻找合适的版本,一般来说比当前版本(#uname -r检查)略高一些。并使用命令
#sudo tar xzvf [源码] -C /usr/src/
解压文件到/usr/src处。#sudo make menuconfig
设置或者加载.config设置文件,menuconfig是根据源码中的kconfig而来,对应的内容是根据kconfig(后文详细描述)。(可选)
#sudo make mrproper
,清除之前编译生成的文件。一般用于非第一次情况,第一次就无需使用了。个人不推荐使用此条命令,如果是为了编译内核娱乐,则编译一次够了;第二次乃至后面无数次编译都是为了调试内核,既然调试内核就不要使用此命令清除其他命令生成的文件。因为编译一次内核需要花费很长时间,而之前编译一次后,后续修改的部分对应的文件才作调整,即已经编译后的内核再做修改很快就能重新编译成功了。#sudo make
#sudo make modules_install
如果在配置config时选择了编译某些模块,则需要使用此命令。个人建议,新手都选择此命令。#sudo make install
(安装,同时更新grub)
编译eCryptfs(模块“M”)
Menuconfig(对于正常编译内核来说,这是唯一改动之处)
- 修改第3步:
#sudo make menuconfig
。
由于需要将eCryptfs作为模块化方式编译至内核,所以需要修改.config设置文件。
(1)阅读fs/ecryptfs/kconfig文件(如下所示)。
最重要的两行,第一行表示在menuconfig中显示的标题为“eCrypt filesystem layer support (EXPERIMENTAL)”;第二行表示依赖关系,eCryptfs依赖于EXPERIMENTAL、KEYS、CRYPTO和ENCRYPTED_KEYS,这四个均在其他目录下的kconfig中出现,要么是“config XXX”、要么是“menuconfig XXX”。
(2)找到上述四个config到对应的目录下的kconfig。
个人建议可以在Linux下搜索:#grep -rl "config XXX" /usr/src/linux-3.3.8/
即可。结果:
a. “EXPERIMENTAL”:在init/kconfig中,对应的标题叫“Prompt for development and/or incomplete code/drivers”。表示尚在开发中或尚未完成的代码和驱动,默认为“N”。
b. “KEYS”:在security/kconfig中,对应的标题叫“Enable access key retention support”。表示内核安全部分的密钥管理。
c. “CRYPTO”:在crypto/kconfig中,对应的标题叫“Cryptographic API”。表示内核密码学算法接口。
d. “ENCRYPTED_KEYS”:在security/kconfig中,为标题“Enable access key retention support”下的子标题“ENCRYPTED KEYS”。表示内核安全部分的密钥管理中的密钥支持部分。
注:上述具体对应的图片见附录B(图中遇到部分可以使用空格选择,附录B中选择编译进内核和模块化方式编译均可)。
常见问题
sudo make出错
错误内容如下:
ERROR: “__modver_version_show” [drivers/staging/rts5139/rts5139.ko] undefined!
WARNING: modpost: Found 5 section mismatch(es).
To see full details build your kernel with:
‘make CONFIG_DEBUG_SECTION_MISMATCH=y‘
make[1]: * [__modpost] Error 1
make: * [modules] Error 2
仔细观察错误部分(如图红色部分),表示出错位置在drivers/staging/rts5139处(可以查看对应的源代码)。rts5139表示读卡器驱动,所以这里存在两种解决方式:
1. (Recommended)取消staging包含的所有驱动,因为staging help解释的很清楚,如果是用于improvement则可以编译,否则就无需编译。步骤:到第二张图片选择“N”即可。
2. 取消staging中的rts5139驱动。步骤:到第三张图片选择“N”即可。
注:staging help解释如下图:
附录A
README(源码)
kernel2.4.0:/README
kernel3.3.8:/README
附录B
EXPERIMENTAL
KEYS
CRYPTO
ENCRYPTED_KEYS
eCryptfs
Other issues:
1. linux 内核编译时出现scripts/sign-file.c:23:30: fatal error: openssl/opensslv.h错误的解决办法:
缺少组件:sudo apt-get install libssl-dev