内核模块是linux向外部提供的一个接口,全称为可加载内核模块(Loadable Kernel Module),简称模块。模块是具有独立功能的程序,它可以被单独编译,但不能独立运行,在运行时它被链接到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不一样的。模块由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序和其他内核上层功能。
因此模块具有两大特点:
• 模块本身不被编译如内核映像,从而控制内核的大小
• 模块一旦被加载,就与内核中的其他部分完全一样,它们具有与其他内核代码相同的权限和职责
内核模块就是可以在系统运行时动态地安装和卸载的内核功能单元,是指在系统引导完毕后还可以加载、卸载、启动或停止的内核子系统。利用这个机制可以无需对整个内核重新编译链接,将内核模块动态插入运行中的内核,成为内核的一个有机组成部分。它不同于普通的应用程序,不能调用位于用户态下的C库函数,只能调用linux内核提供的函数。
通常情况下,用户利用系统提供的插入或移走模块工具实现内核模块的装卸。
内核和系统版本查看
内核版本查看
[root@test253202~]# uname -a
Linuxtest253202 2.6.18-308.el5 #1 SMP Tue Feb 21 20:06:06 EST 2012 x86_64 x86_64x86_64 GNU/Linux
系统版本查看
[root@test253202~]# lsb_release -a
LSBVersion: :core-4.0-amd64:core-4.0-ia32:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-ia32:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-ia32:printing-4.0-noarch
DistributorID: CentOS
Description: CentOS release 5.8 (Final)
Release: 5.8
Codename: Final
该命令适用于所有的linux,包括Redhat、SuSE、Debian等发行版,但是要安装lsb。
[root@test253202~]# cat /etc/issue
CentOSrelease 5.8 (Final)
Kernel\r on an \m
[root@test253202~]#
动态模块和静态模块
动态模块是指模块代码被单独存放在一个文件中用来扩展linux本身的功能,因此linux下有多少模块,结构中心的大小不会有太大的变化,可以根据需要使用modprobe将需要的模块加入内存,暂时不用的模块从内存中移除,实现内存使用的最优化。动态模块的文件存放在/lib/modules/kernel_version/路径下,并使用*.ko作为模块的文件名。在这个目录中内核模块保存在/kernel目录下,
[NSOS1.1 ~]# cd /lib/modules/2.6.18-238.NSOS/kernel/ #可用uname –r命令查看内核版本号
[NSOS1.1 kernel]# ll
total28
drwxr-xr-x 3 root root 4096 Apr 21 2015 arch #与硬件平台相关的项目如cpu等级
drwxr-xr-x 2 root root 4096 Jan 21 11:29 crypto #核心支持的加密技术如MD5
drwxr-xr-x42 root root 4096 Jan 21 11:29 drivers #硬件驱动程序如显卡网卡pci等
drwxr-xr-x32 root root 4096 Apr 21 2015 fs #核心所支持的文件系统
drwxr-xr-x 4 root root 4096 Jan 21 11:29 lib #函数库
drwxr-xr-x30 root root 4096 Jan 21 11:29 net #保存以太网模块与网络有关的各项协议数据
drwxr-xr-x 9 root root 4096 Jan 21 11:29 sound #保存声卡模块
[NSOS1.1 kernel]#
静态模块指的是该模块的代码已结合到结构中心,因此静态模块数越多,结构中心越大,静态模块会随着结构中心一起加载到内存中。
一般会把kernel(结构中心)以vmlinuz-kernel version的形式保存再/boot路径下。
[NSOS1.1 kernel]# cd /boot
[NSOS1.1 boot]# ll
total14228
-rw-r--r--1 root root 67318 Apr 21 2015 config-2.6.18-238.NSOS
drwxr-xr-x2 root root 4096 Oct 20 21:39 grub
-rw-------1 root root 6930038 Oct 20 21:50 initrd-2.6.18-238.NSOS.img
-rw-r--r--1 root root 1267088 Apr 21 2015System.map-2.6.18-238.NSOS
-rw-r--r--1 root root 2093660 Apr 21 2015vmlinuz-2.6.18-238.NSOS
可以查看系统某一功能是以动态模块还是静态模块的形式存在,使用如下方法
#以conntrack功能为例
[NSOS1.1 boot]# cat config-2.6.18-238.NSOS | grep CONNTRACK
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_CONNTRACK_MARK=y
CONFIG_IP_NF_CONNTRACK_SECMARK=y
CONFIG_IP_NF_CONNTRACK_EVENTS=y
CONFIG_IP_NF_CONNTRACK_NETLINK=m
[NSOS1.1 boot]#
过滤当时编译这个内核时所使用的配置文件,出现“=m”,就是动态模块,“=y”就是静态模块。
也可以通过内核模块列表,每个不同版本的内核都有自己专属的模块清单列表,位于/lib/modules/Kernel_Version/modules.dep文件中,如果可以找到ip_conntrack.ko字符串,则是以动态模块存在。
modules.dep文件记录了在核心支持的模块的各项依赖性,使用dpmod 命令即可创建该文件,运行该命令时,depmod会主动分析当前核心的模块,并且重新写入/lib/modules/’uname
-r’/modules.dep中。通常,新的驱动程序模块编译完后,根据核心模块放置的目录放好,然后输入depmod,更新modules.dep,核心就能识别该模块。
模块的编译
编译模块是伴随着编译内核一起完成的。各个模块被分别编译并链接成一组目标文件,这些文件能被载入正在运行的内核,或从正在运行的内核中卸载。
虽然linux规定,只有根目录文件系统不能编译成模块,但建议不要把Ethernet hardware
drivers、SCSI CD-ROM drivers这两个设备编译成模块,而是直接编译进内核,使用效果会更好。另外的一些设备只能编译成模块来使用,它们是并行打印机、并行端口驱动器、PLIP守护进程。
内核编译过程中对模块的支持,需要设置以下几个选项。
>>Enable loadable modulesupport(CONFIG_MODULES)[y/n/?]
询问是否需要可加载的模块,选择yes,即不需要编译到内核里。
>>Set versioninformation on all symbols for modules(CONFIG_MODVERSIONS)[y/n/?]
这一项选择是否给模块附加版本信息,有时候模块和内核版本不同,通常选择no。
>>Kernel moduleloader(CONFIG_KMOD)[y/n/?]
所编译的模块只有在你使用加载程序(insmod或depmod)之后才开始工作,这一项选择yes后,内核就会在需要使用该模块的时候自动调用。
在配置内核相关选项后,对模块的管理还需进行如下操作:
[root@toor~]# make #编译源程序
[root@toor~]# make dep;
[root@toor~]# make clean; #删除不需要的文件
[root@toor~]# makde modules; #把linux/modules目录下模块编译一遍
[root@toor~]# make modules_install #把所有编译好的模块复制到/lib/modules/’uname -r’/下
[root@toor~]#
最后,为目标系统添加内核模块的配置文件/etc/modprobe.conf,以便让系统在运行的时候可以自动加载内核模块。开机自动挂载模块位于该配置文件中,在该文件中写入了模块的加载命令或模块的别名定义等,如果想让某些模块开机自动加载,就可在该文件中写入。
alias eth0 8139t00
#系统启动时,会自动加载8139too模块,同时指定网络设备8139too的别名为eth0
或者在rc.local中加入insmod命令语法。