[转帖] 内核编译学习笔记之完整篇(v1.1.1)

本文档详细介绍了Linux内核编译的全过程,包括编译前的准备工作、编译方式、内核源码目录结构、2.4和2.6内核的编译步骤、补丁处理以及相关工具的使用。内容涵盖从检查编译环境到生成rpm包,旨在帮助读者理解并成功编译自定义内核。
摘要由CSDN通过智能技术生成
 注 :该文章参考了如下内容 :

A)kernel-HOWTO

B)Module-HOWTO

C)man 手册

D)CU : RedHat Linux 2.6内核如何build kernel-sourcecode的rpm包 :

          http://linux.chinaunix.net/bbs/v ... code%B5%C4rpm%B0%FC

作者 :ailms <ailms{@}qq{dot}com>

版本 :v1.1.1

完成时间  :2007/09/29 22:48

**************************************************************************************


下面的东西都是在俺的 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 、splitdiff、combinediff 命令的使用 (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

[Copy to clipboard] [ - ]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 来加上该权限

[Copy to clipboard] [ - ]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 <target> 2>&1 |tee /tmp/make-<target>.out

6、仔细阅读 tarball 中自带的 README 文件、Documentation/HOWTO 文件以及任何与你此次编译相关的文件

7、make menuconfig 过程中如果有不懂的选项,可以选择 <help> ,如果还是看不懂,就按照建议说的做

二、编译内核的方式

你可以通过 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 内核的 :

[Copy to clipboard] [ - ]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 用的。其结构是 :

[Copy to clipboard] [ - ]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-<release>/ 就是编译新版 kernel 时产生的目录。如果是编译其他的 src rpm 也会生成相应的目录         

RPMS/ 是存放编译好的二进制 rpm 包的目录                                                                       

RPMS/<platform>/ 是按平台区分的存放二进制 rpm 包的目录,编译后的二进制 rpm 在那个目录可以通过 $(arch) 命令获知                                                                                                               

SOURCES/ 是存放 source rpm 中的 tar.gz 的内容的。编译前会把 tar.gz 的内容解压到这里                               

SPECS/ 目录是存放 source rpm 中的 spec 文件的                                                                     

SRPMS/ 目录是存放编译好的 source rpm 的。如果你指定不生成 source rpm ,则该目录下不会有内容                       
                                                                                                                 
       
下面是 2.6 内核的 :

[Copy to clipboard] [ - ]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]#


[Copy to clipboard] [ - ]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 有稍微不同,具体待各位自己发现

gyjyxj 2007-10-31 16:25
四、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.-<your_version>

            再把 /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 才有这个权限。

五、2.4 下如何单独编译某个模块

有时候我们编译好了内核,模块文件也生成了。但在日后的使用过程中想增加某个模块应该怎么办呢?下面就以增加 reiserfs 、jfs 、xfs 模块为例进行说明。

当前的内核版本是 2.4.35.normal ,所以新生成的模块也将放在 /lib/modules/2.4.35.normal/fs/ 下

1、执行 make dep 2>&1 |tee /tmp/make_dep.out

2、复制 Makefile 为 Makefile.onlymodule

3、修改 Makefile.onlymodule 的 EXTRAVERSION 为 .onlymodule 。之所以这么做是因为不想覆盖当前内核的模块。
         
    也就是把 Makefile.onlymodule 的 SUBDIRS 为 :SUBDIRS =fs/reiserfs fs/jfs fs/xfs
             
4、执行make -f Makefile.onlymodule modules 2>&1 |tee /tmp/make_only_modules.out 生成上面的模块

    记得要加上 -f 参数,否则使用的还是 Makefile ,而不是 Makefile.onlymodule 文件
                               
5、执行make -f Makefile.onlymodule modules_install 2>&1 |tee /tmp/make_only_modules_install.out 安装模块

6、下面把生成好的模块文件拷贝到当前内核的模块目录下

[Copy to clipboard] [ - ]CODE:
[root@mail fs]# cd /lib/modules/2.4.35.onlymodule/kernel/fs
[root@mail fs]#
[root@mail fs]# ll
total 12
drwxr-xr-x    2 root    root        4096 Sep 19 01:15 jfs
drwxr-xr-x    2 root    root        4096 Sep 19 01:15 reiserfs
drwxr-xr-x    2 root    root        4096 Sep 19 01:15 xfs
[root@mail fs]#       
[root@mail fs]# uname -a
Linux mail.bob.com 2.4.35.normal #1 SMP Wed Sep 19 00:46:00 CST 2007 i686 i686 i386 GNU/Linux
[root@mail fs]#
[root@mail fs]# cp -a * /lib/modules/2.4.35.normal/kernel/fs/
[root@mail fs]#
可以看到上面的 /lib/modules/2.4.35.onlymodule/kernel/fs/ 下只有 jfs/、reiserfs/、xfs/ 三个目录,这就是因为 SUBDIRS 指定只生成这3个目录而已。

所以如果我们上面不修改 EXTRAVERSION 的话,则会把当前内核的模块目录(/lib/modules/2.4.35.normal/) 下的所有其他内容都删除,

再拷贝这3个目录 !!

而在 Kernel-HOWTO 中则没有修改 EXTRAVERSION 一步,直接修改 SUBDIRS ,结果就如同上面所说

7、这样我们就有了 reiserfs、jfs、xfs 文件系统的模块了。下面执行 depmod -a 生成新的 modules.dep 文件

注 :最好先备份原来的 /lib/modules/2.4.35.normal/modules.dep 文件,再执行 depmod

[Copy to clipboard] [ - ]CODE:
[root@mail modules]# depmod -a
[root@mail modules]# ll /lib/modules/2.4.35.normal/modules.dep
-rw-r--r--    1 root    root        8363 Sep 19 01:18 /lib/modules/2.4.35.normal/module
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值