当前位置:Linux教程 - Linux综合 - Linux系统单一内核模块编译过程解析

Linux系统单一内核模块编译过程解析

单一模块编译,想象两个情况:

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

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

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

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

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

如果您的硬件开发商有提供驱动程序的话,那么真的很好解决,直接下载该原始码,重新编译, 将他放置到核心模块该放置的地方后,呵呵!就能够使用了!举例来说,如果您不想使用核心原本提供的 Intel 网络卡模块,而想使用 Intel 官方释出的最新模块,例如下面这个例子:

模块说明与下载:http: //downloadfinder.intel.com/ ... l/Detail_Desc.ASPx? agr=Y&Inst=Yes&ProdUCtID=993&DwnldID=2896&strOSs=39&OSFullName=Linux*〈=eng

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

1. 将档案解压缩:

[root@linux ~]# cd /usr/local/src

[root@linux src]# tar -zxvf /root/e100-3.4.14.tar.gz

[root@linux src]# cd e100-3.4.14

2. 开始进行编译与安装:

[root@linux e100-3.4.14]# vi README <==注意查一下该档案内容

[root@linux e100-3.4.14]# cd src

[root@linux src]# make

# 此时您会看到出现如下这一行:

# make[1]: Entering Directory `/usr/src/kernels/2.6.13-1.1532_FC4-i686'

# 这代表这个驱动程序在编译时,会去读取的核心原始码 include file

# 的目录所在!有兴趣的朋友,务必查阅一下 Makefile 啦!

[root@linux src]# ls -l

-rw-r--r-- 1 root root 77908 Jul 2 08:24 e100.c

-rw-r--r-- 1 root root 351351 Dec 5 00:48 e100.ko

-rw-r--r-- 1 root root 4775 Dec 5 00:48 e100.mod.c

-rw-r--r-- 1 root root 39684 Dec 5 00:48 e100.mod.o

-rw-r--r-- 1 root root 312564 Dec 5 00:48 e100.o

-rw-r--r-- 1 root root 21092 Jul 2 08:24 ethtool.c

-rw-r--r-- 1 root root 43258 Jul 2 08:24 kcompat.h

-rw-r--r-- 1 root root 9610 Jul 2 08:24 Makefile

3. 开始将该模块移动到核心目录,并且更新模块相依属性!

[root@linux src]# cp e100.ko \

> /lib/modules/`uname -r`/kernel/drivers/net

[root@linux src]# cd /lib/modules/`uname -r`

[root@linux 2.6.13-1.1532_FC4]# depmod -a

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

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

举个例子来说,目前FC4 的核心就是 2.6 版,而且也有 NTFS 的原始码,只不过, FC4 就是没有将这个模块给他编译起来!那我能否使用目前的核心原始码进行NTFS 档案系统的模块编译呢?当然可以啊!不过,我是否需要整个核心编译的过程从头来一次呢?

我们首先到目前的核心原始码所在目录下达 make menuconfig , 然后将 NTFS 的选项设定成为模块,之后直接下达:

make fs/ntfs/

那么ntfs 的模块就会自动的被编译出来了!可惜的是,预设的 FC4 核心原始码并没有附上所有的程序代码, 仅有提供相关的 Makefile 档案而已,伤脑筋~ 因此,您仅能以我们刚刚才建立的 /usr/src/linux-2.6.14.2 这个目录, 直接下达 make fs/ntfs 来建立起 ntfs.ko 这个模块~然后将该模块复制到 /lib/modules/2.6.14.2/kernel/fs/ntsf/ 目录下, 再去到 /lib/modules/2.6.14.2 底下执行 depmod -a ,呵呵~ 就可以在原来的核心底下新增某个想要加入的模块功能啰。

核心模块管理: lsmod, modinfo, modprobe, insmod, rmmod...

核心与核心模块是分不开的,至于驱动程序模块在编译的时候,更与核心的原始码功能分不开~ 因此,您必须要先了解到:核心、核心模块、驱动程序模块、核心原始码与标头档案的相关性,然后才有办法了解到为何编译驱动程序的时候老是需要找到核心的原始码才能够顺利编译!然后也才会知道,为何当核心更新之后,自己之前所编译的核心模块会失效~

此外,与核心模块有相关的,还有那个很常被使用的 modprobe 指令,以及开机的时候会读取到的模块定义数据文件 /etc/modprobe.conf ,这些资料您也必须要了解才行~相关的指令说明我们已经在开机流程与 loader 文章内谈过了, 您应该要自行前往了解。

(出处:http://www.sheup.com)