第二十六章、Linux 核心编译与管理
最近升级日期:2009/09/18

大标题的图示额外(单一)核心模块编译

我们现在知道核心所支持的功能当中,有直接编译到核心内部的,也有使用外挂模块的,外挂模块可以简单的想成就是驱动程序 啦!那么也知道这些核心模块依据不同的版本,被分别放置到 /lib/modules/$(uname -r)/kernel/ 目录中,各个硬件的驱动程序则是放置到 /lib/modules/$(uname -r)/kernel/drivers/ 当中!换个角度再来思考一下,如果刚刚我自己编译的数据中,有些驱动程序忘记编译成为模块了,那是否需要重新进行上述的所有动作? 又如果我想要使用硬件厂商释出的新驱动程序,那该如何是好?


小标题的图示编译前注意事项

由於我们的核心原本就有提供很多的核心工具给硬件开发商来使用, 而硬件开发商也需要针对核心所提供的功能来设计他们的驱动程序模块,因此, 我们如果想要自行使用硬件开发商所提供的模块来进行编译时,就需要使用到核心所提供的原始档当中, 所谓的标头文件 (header include file) 来取得驱动模块所需要的一些函式库或标头的定义啦! 也因此我们常常会发现到,如果想要自行编译核心模块时,就得要拥有核心原始码嘛!

那核心原始码我们知道他是可能放置在 /usr/src/ 底下,早期的核心原始码被要求一定要放置到 /usr/src/linux/ 目录下,不过,如果你有多个核心在一个 Linux 系统当中,而且使用的原始码并不相同时, 呵呵~问题可就大了!所以,在 2.6 版以后,核心使用比较有趣的方法来设计他的原始码放置目录, 那就是以 /lib/modules/$(uname -r)/build 及 /lib/modules/$(uname -r)/source 这两个连结档来指向正确的核心原始码放置目录。如果以我们刚刚由 kernel 2.6.30.3 创建的核心模块来说, 那么他的核心模块目录底下有什么咚咚?

[root@www ~]# ll -h /lib/modules/2.6.30.3vbird/
lrwxrwxrwx  1 root root   31  7月 30 14:29 build -> /usr/src/kernels/linux-2.6.30.3
drwxr-xr-x 10 root root 4.0K  7月 30 14:30 kernel
-rw-r--r--  1 root root 337K  7月 30 14:31 modules.alias
-rw-r--r--  1 root root   69  7月 30 14:31 modules.ccwmap
-rw-r--r--  1 root root 224K  7月 30 14:31 modules.dep
....(中间省略)....
lrwxrwxrwx  1 root root   31  7月 30 14:29 source -> /usr/src/kernels/linux-2.6.30.3

比较有趣的除了那两个连结档之外,还有那个 modules.dep 文件也挺有趣的, 那个文件是记录了核心模块的相依属性的地方,依据该文件,我们可以简单的使用 modprobe 这个命令来加载模块呢!至於核心原始码提供的标头档,在上面的案例当中, 则是放置到 /usr/src/kernels/linux-2.6.30.3/include/ 目录中,当然就是藉由 build/source 这两个连结文件来取得目录所在的啦!^_^

由於核心模块的编译其实与核心原本的原始码有点关系的,因此如果你需要重新编译模块时, 那除了 make, gcc 等主要的编译软件工具外,你还需要的就是 kernel-devel 这个软件!记得一定要安装喔!而如果你想要在默认的核心底下新增模块的话,那么就得要找到 kernel 的 SRPM 文件了! 将该文件给他安装,并且取得 source code 后,才能够顺利的编译喔!


小标题的图示单一模块编译

想像两个情况:

  • 如果我的默认核心忘记加入某个功能,而且该功能可以编译成为模块,不过, 默认核心却也没有将该项功能编译成为模块,害我不能使用时,该如何是好?

  • 如果 Linux 核心原始码并没有某个硬件的驱动程序 (module) ,但是开发该硬件的厂商有提供给 Linux 使用的驱动程序原始码,那么我又该如何将该项功能编进核心模块呢?

很有趣对吧!不过,在这样的情况下其实没有什么好说的,反正就是 『去取得原始码后,重新编译成为系统可以加载的模块』啊!很简单,对吧!^_^! 但是,上面那两种情况的模块编译行为是不太一样的,不过,都是需要 make, gcc 以及核心所提供的 include 标头档与函式库等等。


  • 硬件开发商提供的额外模块

很多时候,可能由於核心默认的核心驱动模块所提供的功能你不满意,或者是硬件开发商所提供的核心模块具有更强大的功能, 又或者该硬件是新的,所以默认的核心并没有该硬件的驱动模块时,那你只好自行由硬件开发商处取得驱动模块, 然后自行编译罗!

如果你的硬件开发商有提供驱动程序的话,那么真的很好解决,直接下载该原始码,重新编译, 将他放置到核心模块该放置的地方后就能够使用了!举个例子来说,为了省电,鸟哥在 2009 年初买了整合型主板来架设家用的服务器,没想到 CentOS 5.1 以前的版本对鸟哥新买的主板内建网卡支持度不足, 使用的网卡驱动程序 r8169 有问题!搜寻了 google 才发现大家都有这个问题。解决方法就是到 Realtek 官网下载网卡驱动程序来编译即可。

你可以利用各种方法将他下载后,假设这个文件放置到 /root ,那么直接将他解压缩吧! 之后就可以读一读 INSTALL/README ,然后找一下 Makefile ,就能够编译了。整体流程有点像这样:

# 1. 将文件解压缩:
[root@www ~]# cd /usr/local/src
[root@www src]# tar -jxvf /root/r8168-8.013.00.tar.bz2
[root@www src]# cd r8168-8.013.00/

# 2. 开始进行编译与安装:
[root@www r8168-8.013.00]# vi readme  <==注意查一下该文件内容
[root@www r8168-8.013.00]# make clean modules
[root@www r8168-8.013.00]# ll src/*.ko  <==创建底下的模块档!
-rw-r--r-- 1 root root 112216  7月 31 01:11 src/r8168.ko
[root@www r8168-8.013.00]# make install
install -m 744 -c r8168.ko /lib/modules/2.6.30.3vbird/kernel/drivers/net/
# 重点在上面这行!会发现模块已经被移动到核心模块目录!

4. 升级模块相依属性!
[root@www r8168-8.013.00]# depmod -a

有趣吧!透过这样的动作,我们就可以轻易的将模块编译起来,并且还可以将他直接放置到核心模块目录中, 同时以 depmod 将模块创建相关性,未来就能够利用 modprobe 来直接取用啦! 但是需要提醒你的是,当自行编译模块时, 若你的核心有升级 (例如利用自动升级机制进行线上升级) 时,则你必须要重新编译该模块一次, 重复上面的步骤才行!因为这个模块仅针对目前的核心来编译的啊!对吧!


  • 利用旧有的核心原始码进行编译

如果你后来发现忘记加入某个模块功能了,那该如何是好?其实如果仅是重新编译模块的话, 那么整个过程就会变的非常简单!我们先到目前的核心原始码所在目录下达 make menuconfig , 然后将 NTFS 的选项配置成为模块,之后直接下达:

make fs/ntfs/

那么 ntfs 的模块 (ntfs.ko) 就会自动的被编译出来了! 然后将该模块复制到 /lib/modules/2.6.30.3vbird/kernel/fs/ntsf/ 目录下, 再运行 depmod -a ,呵呵~就可以在原来的核心底下新增某个想要加入的模块功能罗~ ^_^


小标题的图示核心模块管理

 
     
http://linux.vbird.org is designed by VBird during 2001-2011. ksu.edu 

本网页主要以Firefox配合解析度 1024x768 作为设计依据     鸟哥自由软件整合应用研究室