制作initrd(1):向initrd内部更新驱动模块
虽然initrd的存在感不强,但却是本文核心角色。这起源于最近制作LFS,大部分时间花在制作initrd上;另外公司外包一个小系统出去,其核心部分也是定制initrd。出于这些原因,记录于此以备查阅。
按grub.cfg的设置,initrd常化名为initrd.img-`uname -r`定居于/boot目录。编译内核代码执行make modules_install后会生成initrd.img,这是一个经cpio打包然后gzip压缩的文件,因此,完全可以把initrd.img解剖了研究。
- #file initrd.img-3.13.0
- initrd.img-3.13.0:gzip compressed data
- #mv initrd.img-3.13.0 initrd.img-3.13.0.gz
- #gunzip initrd.img-3.13.0.gz
- #file initrd.img-3.13.0
- initrd.img-3.13.0:ASCII cpio archive
- #cpio -i --make-directories < initrd.img-3.13.0 #解包
- #ls
- bin init run conf sbin etc lib scripts
从initrd.img解压的结果来看,initrd.img文件中也包含了一个跟文件系统的雏形。据悉,如果配置内核源码,使之支持initramfs(make menuconfig时在General setup中选中Inital RAM filesystem and RAM disk选项),当系统启动时,内核会创建一个ramdisk,把initrd.img的内容解压到其中,这样内核中就有一个临时个根文件系统,加载类似scsi驱动。关于这个根文件系统的作用,我将另起一文记录。
有过嵌入式经验的读者都知道,这个根文件系统中有个至关重要的用户态进程--udev,负责加载模块。上文已经说道这个临时根文件系统会加载scsi模块,可是scsi模块在哪?可以从udev的行为来推出模块路径。udev启动时按/etc/modprobe.d/目录下的规则文件(*.rules)的设置,去/lib/modules/`uname -r`目录下加载模块。由此可知scsi模块路径十有八九在此了:
- #以下命令执行在上面被肢解的initrd.img文件夹下
- #cd lib/modules/3.13.0/kernel/drivers
- #ls
- ata ... block ... scsi uio
这些模块是执行make modules_install时被安装到/lib/modules/`uname -r`/目录下,而在make modules_install的结尾部分,Makefile会调用mkinitramfs将一些模块添加到initrd中。
看到这,我觉得大家对initrd有个感性认识了。那好,我有个问题,如何在系统启动时加载一个模块?目前,我知道3种方式:
1.在类似/etc/initrc等配置文件的末尾加入insmod xx.ko,这个是最容易想到的
2.另一种方式,就是在/etc/modules文件中添加开机时需要装入的模块的模块名,来看下modules自己的注释:
- # /etc/modules: kernel modules to load at boot time.
- #
- # This file contains the names of kernel modules that should be loaded
- # at boot time, one per line. Lines beginning with "#" are ignored.
以我的环境为例:我用的os是公版的ubuntu 12.04,另外, 桌面上待编译的内核为linux-3.13
- root@ubuntu:~# uname -r
- 3.13.0-32-generic
- root@ubuntu:~# cat /etc/issue
- Ubuntu 12.04.5 LTS \n \l
- root@ubuntu:~# cd ~/Desktop/linux-3.13/
- root@ubuntu:~/Desktop/linux-3.13# pwd
- /root/Desktop/linux-3.13
两个内核的区别是,我往待编译的内核上添加了2个测试模块:
经过make all&&make modules_install&&make install后,在/boot/grub/grub.cfg中有两个启动项:
- #公版启动项
- menuentry 'Ubuntu, with Linux 3.13.0-32-generic' --class ubuntu --class gnu-linux --class gnu --class os {
- recordfail
- gfxmode $linux_gfx_mode
- insmod gzio
- insmod part_msdos
- insmod ext2
- set root='(hd0,msdos1)'
- search --no-floppy --fs-uuid --set=root 9a661d2c-4456-4d23-93f2-60544bc54fe3
- linux /boot/vmlinuz-3.13.0-32-generic root=UUID=9a661d2c-4456-4d23-93f2-60544bc54fe3 ro quiet splash $vt_handoff
- initrd /boot/initrd.img-3.13.0-32-generic
- }
- #添加了Simple模块的启动项
- menuentry 'Ubuntu, with Linux 3.13.0' --class ubuntu --class gnu-linux --class gnu --class os {
- <span style="white-space:pre"> </span>recordfail
- <span style="white-space:pre"> </span>gfxmode $linux_gfx_mode
- <span style="white-space:pre"> </span>insmod gzio
- <span style="white-space:pre"> </span>insmod part_msdos
- <span style="white-space:pre"> </span>insmod ext2
- <span style="white-space:pre"> </span>set root='(hd0,msdos1)'
- <span style="white-space:pre"> </span>search --no-floppy --fs-uuid --set=root 9a661d2c-4456-4d23-93f2-60544bc54fe3
- <span style="white-space:pre"> </span>linux<span style="white-space:pre"> </span>/boot/vmlinuz-3.13.0 root=UUID=9a661d2c-4456-4d23-93f2-60544bc54fe3 ro quiet splash $vt_handoff
- <span style="white-space:pre"> </span>initrd<span style="white-space:pre"> </span>/boot/initrd.img-3.13.0
- }
- # /etc/modules: kernel modules to load at boot time.
- #
- # This file contains the names of kernel modules that should be loaded
- # at boot time, one per line. Lines beginning with "#" are ignored.
- lp
- simple_ops_export
- simple
- root@ubuntu:~# lsmod|grep -i simple
- simple 799 0
- simple_ops_export 1184 1 simple
- root@ubuntu:~# uname -r
- 3.13.0
- root@ubuntu:~# uname -r
- 3.13.0-32-generic
- root@ubuntu:~# lsmod|grep -i simple
- root@ubuntu:~#
这种方法需要借用mkinitramfs套件,mkinitramfs会把/lib/modules/`uname -r`目录下一些启动必须的模块添加到initramfs中。如果用户需要手动添加一些模块,可以通过/etc/initramfs-tools/modules文件中加入模块名来实现。
来看下修改该文件前后initrd.img的变化:
3-1):默认情况下的/etc/initramfs-tools/modules
- # List of modules that you want to include in your initramfs.
- # They will be loaded at boot time in the order below.
- #
- # Syntax: module_name [args ...]
- #
- # You must run update-initramfs(8) to effect this change.
- #
- # Examples:
- #
- # raid1
- # sd_mod
- # Beginning of the block added by the VMware software - DO NOT EDIT
- vmxnet3
- vmw_pvscsi
# End of the block added by the VMware software
- root@ubuntu:~# update-initramfs -u -k 3.13.0
- cp /boot/initrd.img-3.13.0 ~/Desktop/initrd.img-3.13.0.gz
#gunzip ~/Desktop/initrd.img-3.13.0.gz
#cpio -i --make-directories < initrd.img-3.13.0
root@ubuntu:~/Desktop# cd lib/modules/3.13.0/
root@ubuntu:~/Desktop/lib/modules/3.13.0#ls
modules.alias.bin modules.devname modules.symbols
modules.dep modules.order modules.symbols.bin
3-2):修改/etc/initramfs-tools/modules后
- # List of modules that you want to include in your initramfs.
- # They will be loaded at boot time in the order below.
- #
- # Syntax: module_name [args ...]
- #
- # You must run update-initramfs(8) to effect this change.
- #
- # Examples:
- #
- # raid1
- # sd_mod
- # Beginning of the block added by the VMware software - DO NOT EDIT
- vmxnet3 #附注,这里可以看出vmware如何添加vmtools模块
- vmw_pvscsi
- simple_ops_export
- sample
- # End of the block added by the VMware software
root@ubuntu:~# update-initramfs -u -k 3.13.0
- cp /boot/initrd.img-3.13.0 ~/Desktop/initrd.img-3.13.0.gz
#gunzip ~/Desktop/initrd.img-3.13.0.gz
#cpio -i --make-directories < initrd.img-3.13.0
root@ubuntu:~/Desktop# cd lib/modules/3.13.0/
root@ubuntu:~/Desktop/lib/modules/3.13.0#ls #多了一个kernel文件夹
- root@ubuntu:~/Desktop/lib/modules/3.13.0# cd kernel/drivers/char
- root@ubuntu:~/Desktop/lib/modules/3.13.0/kernel/drivers/char# ls
- simple_ops_export.ko
- root@ubuntu:~# uname -r
- 3.13.0
- root@ubuntu:~# lsmod|grep -i simple
- simple_ops_export 1184 0
- root@ubuntu:~#
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!