**************************************************************************************注:该文章参考了如下内容:A)kernel-HOWTO
B)Module-HOWTO
C)man手册D)CU : RedHat Linux 2.6内核如何build kernel-sourcecode的rpm包:作者:ailms版本:v1.1完成时间: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内核打补丁:从2.6.10→2.6.12.6九、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 2.9.1.0.25 # ld -v
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-2.6.20.1)有一个scripts/目录,里面有很多有用的脚本,其中一个叫做ver_linux
CODE:
[root@monitor scripts]# ll ver_linux
-rw-r--r-- 1 root root 2569 2002-11-29 ver_linux
[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 2.4.20-8smp #1 SMP Thu Mar 13 17:45:54 EST 2003 i686 i686 i386 GNU/Linux
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 2>&1 |tee /tmp/make-.out6、仔细阅读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-2.4.20-8
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.4.20-8/。有多个内核就有多个这样的目录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-/就是编译新版kernel时产生的目录。如果是编译其他的src rpm也会生成相应的目录RPMS/是存放编译好的二进制rpm包的目录RPMS//是按平台区分的存放二进制rpm包的目录,编译后的二进制rpm在那个目录可以通过$(arch)命令获知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 2.6.9-5.EL-hugemem-i686
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内核编译过程步骤这部分内容随便一搜就很多了,我也就不多说,把大概的过程列一下。这里以编译2.4.35为例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/System.map拷贝到/boot下,重命名为System.map-2.4.35.custom把/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才有这个权限。