2008年1月4日星期五

几个Linux内核模块管理工具

介绍几个Linux内核模块管理的相关工具。

首先是lsmod,我们用它来查看当前加载的模块。

rmmod可以帮我们卸载某个模块,如果该模块被其它模块使用,就会卸载失败,可以查看lsmod输出的第4列来确定模块被哪些模块依赖,先卸载它们,最后卸载被依赖的模块。

modprobe用来加载某个模块,如果该模块依赖其它尚未加载的模块,则一并加载。

depmod用来生成modules.dep文件,modprobe就是通过它来确认模块之间的依赖关系。我们知道,内核和模块都提供了许多符号可供第3方使用,depmod正是依据A模块是否使用了B模块的符号来确定它们的依赖关系的。

depmod -a
Ubuntu中有一些个脚本,如lrm-managerlrm-video,是用来管理版权受限的模块的,lrm的意思是linux restricted modules,如Nvidia的视频驱动。

关于受限驱动模块,你还可以看一下/etc/default/linux-restricted-modules-common文件,在这里可以设定禁止加载哪些模块。

关于启动时哪些模块被加载,或者加载细节等等的一些配置,可以看一下/etc下的modprobe.dmodutils目录和modules文件。

deb文件制作与修改初级

deb文件是Debian/Ubuntu系统的软件包分发格式,就象RedHat/Fedora的rpm。

首先我们来看一下deb包的结构。

随便找一个deb文件,比如说foo.deb:

dpkg -e ../foo.deb
dpkg -x ../foo.deb .
第1条命令在当前路径生成了有一个DEBIAN目录,它是deb包中的控制部分,目录中一般有这么几个文件
  1. control文件中记录了该deb包的元信息,如软件包名,版本,谁打的包,与哪些软件包冲突等等。
  2. md5sums文件中是该软件包要安装到系统中的文件的md5值。
  3. preinst文件是安装之前预处理的脚本。如安装新版本的Apache服务器时可能要先停止正在运行的服务。这个和以下的几个文件都是shell脚本。
  4. prerm文件用于安装前删除一些文件。
  5. postinst文件用于安装后的处理脚本。继续上面的例子,你可以在这里启动新版本的Apache服务。
  6. postrm文件用来在安装后删除一些文件。
第2条命令在当前目录解压了要安装到系统的数据文件,如果以当前目录为根目录,它们的路径就是被安装到系统的路径。

另外再介绍两个解压deb包的命令
ar p ../foo.deb control.tar.gz | tar zxvf -
ar p ../foo.deb data.tar.bz2 | tar jxvf -
这里第1条命令与上面略有不同,它直接将DEBIAN目录下的文件解压到当前目录,而不生成DEBIAN目录,如果你最后还要还原成deb包的话,这会有点不方便。第2条命令的效果则和先前的一样。

你可以按照你的要求,随意增加、删除、修改所有这些文件。如果你要为一个解压即可以运行的软件制作一个deb包,你要做的一般就是安排好目录,添加几个快捷方式。如果是用make;make install自己编译的,我的办法是先用checkinstall生成一个deb包,然后再解开来做一些修改,如果需要的话。

最后再将它们打包成deb文件
cd ..
dpkg -b 待打包目录 软件包名
如上所述,待打包目录形如foo/DEBIAN,foo/usr/bin/... ,这也是为什么上面讲解压时,命令中的deb包都放在上层目录的原因。

2008年1月3日星期四

System.map文件:内核符号-地址转换表

赵炯编译的文章-《System.map文件的作用》 几乎把什么都说了,我就这里做个摘要吧

  1. System.map是在编译内核时自动生成的,由于编译器,内核版本,编译平台等因素,每次编译后的System.map都会不同。
  2. 内核自身并不使用System.map
  3. 所谓内核符号就是变量、函数名等等,它们在内核中的地址可能是这样的:c03441a0
  4. klogd之类的程序使用System.map将内核消息中的地址转换成符号名,以方便人们理解。
  5. /proc/ksyms在2.6内核中换成了/proc/kallsyms,在内核初始化时创建,是当前内核实时的符号-地址表
  6. 应用程序如klogd,会自动在相应目录查找System.map。

initrd.img:内核初始化过程中使用的内存文件系统

initrd.img是一个gzipcpio双重打包的文件,如果你把它解开就会发现,其实它包含了一个微型的根文件系统:

mkdir initrd
cd initrd
cp /boot/initrd.img-2.6.22-14-generic ..
zforce ../*
gunzip ../initrd.img-2.6.22-14-generic.gz
cpio -i -F ../initrd.img-2.6.22-14-generic
ls
其中包含了一些常用的命令,许多脚本,内核模块等等。内核在启动过程中,会将它解压到内存,建立一个临时的用户环境,利用这些工具处理一些必须在这个阶段完成的任务,如加载根设备驱动等等。

重新打包可以这样:
find . | cpio -o -H newc | gzip -9 > ../initrd.gz
Ubuntu上建议用户使用update-initramfs来维护和生成initrd.img,高级用户可以使用mkinitramfs。以前的标准工具mkinitrd似乎不再被使用。其实它们都是一些脚本。
sudo update-initramfs -u -k all
我们可以通过Grub或Lilo给内核传递参数,告诉它应该使用哪一个initrd.img文件:
initrd /boot/initrd.img-2.6.22-14-generic