全部博文(534)
分类: LINUX
2007-09-28 16:44:05
**************************************************************************************
注 :该文章参考了如下内容 :
A)kernel-HOWTO
B)Module-HOWTO
C)man 手册
D)CU : RedHat Linux 2.6内核如何build kernel-sourcecode的rpm包 :
作者 :ailms
完成时间 :2007/09/28 2:03
**************************************************************************************
下面的东西都是在俺的 PC 实验得来的,可能由于环境不同会造成某些结果的不一致,欢迎各位朋友多多指正,补充 ! ^_^
目录
一、编译前的准备工作
二、编译内核的方式
三、/usr/src 目录的结构
四、2.4 内核编译过程步骤
五、2.4 下如何单独编译某个模块
六、关于 “depmod: *** Unresolved symbols ” 的问题
七、2.6 内核编译过程步骤
a) make help
b) 单个模块的编译
c)如何导出当前内核的 .config (v1.1)
d)如何生成 rpm 包 (V1.1)
八、补丁部分
a)diff 命令的基本用法以及如何生成补丁文件
b)补丁文件内容解读
c)patch 命令的用法 :打补丁、测试、恢复(卸载)
d)patchutils 工具包及 lsdiff、grepdiff 命令的使用 (V1.1)
e)补丁的分类 :增量和差分型 [ 注 :资料上并没有明确定义,但为了便于自己记忆,所以借用备份领域的术语 ]
f)如何给 Linux 内核打补丁:从
九、patch-kernel 脚本分析
十、patch-kernel 脚本应用实例
一、编译内核前的准备工作
1、为什么需要编译内核?
需要手工编译内核的理由有很多,例如
a)内核开发
b)新版内核提供了你主机上某个硬件的驱动
c)需要使用新的功能
d)原来的内核过于臃肿,想裁减掉一些不必要的功能
e)其他...
不过编译内核之前还是需要考虑其他事情,如果只是想弄出一个 vmlinuz 来那很简单,关键是该内核日后的使用 :
a)是否只能通过重编译内核来解决,有没有其他的方法
b)新内核是否足够稳定?会否对那些应用产生影响?是否存在兼容性问题?
c)新版本内核有那些已知的漏洞
d)其他
e)欢迎补充!!
2、如果是重新编译现有的内核,最好先备份整个源代码目录
一个 make mrproper 就可以把 .config 文件干掉,到时 make menuconfig 一个个重新选简直是令人抓狂 ,所以最好把该文件备份
3、查看 Documentation/Changes 文件
该文件告诉了要编译该版本的内核所需要的一些软件以及最低版本要求,例如
QUOTE:
Current Minimal Requirements
============================
Upgrade to at *least* these software revisions before thinking you've
encountered a bug! If you're unsure what version you're currently
running, the suggested command should tell you.
Again, keep in mind that this list assumes you are already
functionally running a Linux 2.2 kernel. Also, not all tools are
necessary on all systems; obviously, if you don't have any PCMCIA (PC
Card) hardware, for example, you probably needn't concern yourself
with pcmcia-cs.
o Gnu C 2.95.3 # gcc --version
o Gnu make 3.77 # make --version
o binutils
o util-linux 2.10o # fdformat --version
o modutils 2.4.2 # insmod -V
o e2fsprogs 1.25 # tune2fs
o jfsutils 1.0.12 # fsck.jfs -V
o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs
o pcmcia-cs 3.1.21 # cardmgr -V
o PPP 2.4.0 # pppd --version
o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
4、使用 scripts/ver_linux 脚本进行快速检查
在源代码目录下(假设为 /usr/src/linux-
其中一个叫做 ver_linux
CODE:
[root@monitor scripts]# ll ver_linux
-rw-r--r-- 1 root root 2569
[root@monitor scripts]#
由于没有执行权限,所以用 bash -f 来执行它。当然你也可以用 chmod a+x 来加上该权限
CODE:
[root@monitor scripts]# bash -f ver_linux
If some fields are empty or look unusual you may have an old version.
Compare to the current minimal requirements in Documentation/Changes.
Linux monitor.no7.com
Gnu C 3.2.2
Gnu make 3.79.1
util-linux 2.11y
mount 2.11y
modutils 2.4.22
e2fsprogs 1.32
jfsutils 1.0.17
reiserfsprogs 3.6.4
pcmcia-cs 3.1.31
PPP 2.4.1
isdn4k-utils 3.1pre4
Linux C Library 2.3.2
Dynamic linker (ldd) 2.3.2
Procps 2.0.11
Net-tools 1.60
Kbd 1.08
Sh-utils 4.5.3
Modules Loaded iptable_filter ip_tables autofs e100 microcode nls_iso8859-1 nls_cp437 vfat fat loop lvm-mod keybdev mousedev hid input usb-ohci usbcore ext3 jbd aic7xxx sd_mod scsi_mod
[root@monitor scripts]#
5、最好保存每个 make 命令的输出,例如 make
6、仔细阅读 tarball 中自带的 README 文件、Documentation/HOWTO 文件以及任何与你此次编译相关的文件
7、make menuconfig 过程中如果有不懂的选项,可以选择
二、编译内核的方式
你可以通过 rpm (source rpm 或者 binary rpm)或者 tarball 的方式来编译。
1、安装方面 :
rpm 方式 :简单,可能有厂家专门优化的配置。但缺乏灵活性,一般都会预装很多东西,特别是一大堆的驱动模块
tarball 方式 :复杂、容易出错(例如选少了某个驱动的支持,导致新内核无法正常使用)。但提供足够的灵活性,编译什么东西都由你自己决定。
2、卸载方面 :
rpm 方式 :比较难。因为新内核是通过 rpm -ivh ,而不是 rpm -Uvh ,所以装完之后会有两个 kernel rpm 存在,一旦想卸载的话比较麻烦,rpm -e 会报错
tarball 方式 :很简单,直接把 /boot 下的相关文件和内核源代码树,/lib/modules 对应目录删除,修改 grub.conf 就可以了
三、/usr/src 目录的结构
下面是 2.4 内核的 :
CODE:
[root@mail src]# ll
total 12
drwxr-xr-x 2 root root 4096 Jan 25 2003 debug
lrwxrwxrwx 1 root root 14 Sep 17 06:20 linux-2.4 -> linux-
drwxr-xr-x 16 root root 4096 Sep 17 06:20 linux-2.4.20-8
drwxr-xr-x 7 root root 4096 Sep 17 06:20 redhat
[root@mail src]#
可以看到主要分成两类 :
1、内核源代码目录,例如 linux-
2、redhat/ 目录。该目录是用于编译 sorce rpm 用的。其结构是 :
CODE:
[root@monitor redhat]# find . -maxdepth 2 -type d
.
./BUILD
./BUILD/kernel-2.4.2031.9custom
./RPMS
./RPMS/athlon
./RPMS/i386
./RPMS/i486
./RPMS/i586
./RPMS/i686
./RPMS/noarch
./SOURCES
./SPECS
./SRPMS
[root@monitor redhat]#
BUILD/ 存放编译过程中的临时内容
BUILD/kernel-
RPMS/ 是存放编译好的二进制 rpm 包的目录
RPMS/
SOURCES/ 是存放 source rpm 中的 tar.gz 的内容的。编译前会把 tar.gz 的内容解压到这里
SPECS/ 目录是存放 source rpm 中的 spec 文件的
SRPMS/ 目录是存放编译好的 source rpm 的。如果你指定不生成 source rpm ,则该目录下不会有内容
下面是 2.6 内核的 :
CODE:
[root@mail src]# ll
total 16
drwxr-xr-x 6 root root 4096 Sep 27 17:05 kernels
drwxr-xr-x 7 root root 4096 Sep 16 22:54 redhat
[root@mail src]#
CODE:
[root@mail src]# cd kernels/
[root@mail kernels]# ll
total 32
drwxr-xr-x 17 root root 4096 Sep 16 22:53
drwxr-xr-x 17 root root 4096 Sep 26 21:10 2.6.9-5.EL-i686
drwxr-xr-x 17 root root 4096 Sep 16 22:53 2.6.9-5.EL-smp-i686
drwxrwxr-x 20 root root 4096 Sep 27 17:13 linux-2.6.20.1
[root@mail kernels]#
可以看到把多个内核源代码目录都集中放到 kernels/ 下,而不是直接放在 /usr/src/ 下。同时源代码目录也和 2.4 有稍微不同,具体待各位自己发现
四、2.4 内核编译过程步骤
这部分内容随便一搜就很多了,我也就不多说,把大概的过程列一下。这里以编译
1、解开 tar 包到 /usr/src/ 下
2、 如果是重新编译内核的话,记得备份旧的 .config 文件并执行 make 。不要以 .config.bak 这样的名字备份,因为 make mrproper
会删除 .config.* 文件 !如果是编译新内核的话,把旧的 .config 文件拷贝到新的内核源代码目录下。
3、执行 make clean mrproper
4、 执行 make oldconfig ,这样可以不用经历原来的选择过程,直接使用旧的配置文件否则执行 make menuconfig
5、make dep 检查依赖性是否存在问题
6、编辑 /usr/src/linux/Makefile 的 EXTRAVERSION ,给这个内核加上一个你自己的名称 !例如 '.custom' ,这样编译出来的内核版本就是 2.4.35.custom
不要忘记该步,否则后面的 make modules_install 新产生的模块文件会把 /lib/modules/2.4.35/ 下的内容都覆盖掉。
7、执行 make bzImage 生成内核的二进制文件
8、执行 'make moudles' 和 'make modules_install'
9、第8步是非常久的。
10、使用 cp 把 /usr/src/linux/arch/i386/boot/bzImage 文件拷贝到 /boot 下,重命名为你想要的内核名称,一般是 vmlinuz-2.x.x.-
把 /usr/src/linux-2.4.35/.config 拷贝到 /boot 下,重命名为 config-2.4.35.custom
11、修改 grub.conf 或者 lilo.conf ,加入相应内容。
12、重启并检查新内核是否可用,并检查对应用是否有影响。
13、用 mkbootdisk 命令创建 bootdisk
14、如果有时间可以用 make rpm 创建自己的内核 rpm 包,不过目前只在 rehdat 自己提供的 kernel source rpm 包上成功过,在 kerne.org 下在的源代码
都失败了。
15、执行 make clean 把不用的文件删除
16、把 .config 文件备份到一个安全的位置
注 1 :其实编译内核时不一定要以 root 身份进行,例如你可以把 tar 包解压到你的 HOME 目录下,并按上面一步步做,直至 make modules
但因为 make modules_install 需要写 /lib/modules/ 目录,所以只有 root 才有这个权限。