制作initrd(3):/etc/initramfs-tools/modules配置文件分析
from:http://blog.csdn.net/lixiangminghate/article/details/50061251
制作initrd(3):/etc/initramfs-tools/modules配置文件分析
这是前面:<制作initrd(1):向initrd内部更新驱动模块>一文增补,简单解释在制作initrd过程中一些原理。
<制作initrd(1):向initrd内部更新驱动模块>中提到如果想向initrd.img中添加新的模块,可在/etc/initramfs-tools/modules文件中添加相应模块的模块名及其参数。为什么如此即可?
还是得从update-initramfs脚本说起。update-initramfs通过脚本函数generate_initramfs()进入mkinitramfs脚本。脚本中这几行正好可以解释这个疑问:
- L8:
- CONFDIR="/etc/initramfs-tools"
- ...
- L208:
- for x in "${CONFDIR}/modules" /usr/share/initramfs-tools/modules.d/*; do
- if [ -f "${x}" ]; then
- add_modules_from_file "${x}"
- fi
- done
脚本对/etc/initramfs-tools/modules等文件做add_modules_from_file操作,从函数名就可以看出,实现解析文件内容并向initrd.img添加模块的功能必定在这个函数中。
- add_modules_from_file()
- {
- # Sanity check
- if [ ! -e "${1}" ]; then
- echo "W: add_modules_from_file: arg1='${1}' does not exist." >&2
- return
- fi
- grep '^[^#]' ${1} | while read module args; do
- [ -n "$module" ] || continue
- force_load "${module}" "${args}"
- done
- }
add_modules_from_file接受一个参数,就是配置文件路径,就是for循环中的/etc/initramfs-tools/modules。通过grep逐行读取该文件中的内容(跳过#开始的注释内容),将模块的名字和参数分别读到module和args中,然后传递给force_load。比如/etc/initramfs-tools/modules中有一行内容是vmxnet3,那么在此就是以
- force_load vmxnet3
的形式调用force_load脚本函数
- force_load()
- {
- manual_add_modules ${@}
- #将模块名和参数追加到initrd.img目录结构的conf/modules文件中
- echo "${@}" >>"${DESTDIR}/conf/modules"
- }
下面贴上manual_add_modules的脚本,之前遗漏了。他主要作用是按模块的名字获得模块所在的路径,并获得其依赖的固件,最后一并拷贝到initrd.img目录结构中
- manual_add_modules()
- {
- local kmod firmware
- #以vmxnet3为例 运行modprobe --show-depends vmxnet3 --set-version=3.13.0-32-generic
- #输出insmod /lib/modules/3.13.0-32-generic/kernel/drivers/net/vmxnet3/vmxnet3.ko
- #运行modprobe --show-depends vmxnet3 --set-version=3.13.0-32-generic|awk '/^insmod/ { print $2 }'
- #输出/lib/modules/3.13.0-32-generic/kernel/drivers/net/vmxnet3/vmxnet3.ko
- #这是搜索模块对应的驱动文件
- for kmod in $(modprobe --set-version="${version}" --ignore-install \
- --quiet --show-depends "${1}" | awk '/^insmod/ { print $2 }'); do
- # Prune duplicates
- #如果initrd.img中已经存在该驱动文件 就算了
- if [ -e "${DESTDIR}/${kmod}" ]; then
- continue
- fi
- #否则 连同目录结构一起拷过去
- mkdir -p "${DESTDIR}/$(dirname "${kmod}")"
- cp -pL "${kmod}" "${DESTDIR}/$(dirname "${kmod}")"
- if [ "${verbose}" = "y" ]; then
- echo "Adding module ${kmod}"
- fi
- # Add required firmware
- #列出模块所依赖的farmware
- for firmware in $(modinfo -F firmware "${kmod}"); do
- if [ -e "${DESTDIR}/lib/firmware/${firmware}" ] \
- || [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}" ]; then
- continue
- fi
- # Only print warning for missing fw of loaded module
- # or forced loaded module
- if [ ! -e "/lib/firmware/${firmware}" ] \
- && [ ! -e "/lib/firmware/${version}/${firmware}" ] ; then
- # Only warn about missing firmware if
- # /proc/modules exists
- if [ ! -e /proc/modules ] ; then
- continue
- fi
- if grep -q "^$(basename "${kmod}" .ko)[[:space:]]" \
- /proc/modules \
- || grep -q "^$(basename "${kmod}" .ko)" \
- "${CONFDIR}/modules"; then
- echo "W: Possible missing firmware /lib/firmware/${firmware} for module $(basename ${kmod} .ko)" >&2
- fi
- continue
- fi
- #拷贝firmware到initrd.img目录结构中
- if [ ! -e "${DESTDIR}/lib/udev/firmware.agent" ] \
- && [ -e "/lib/udev/firmware.agent" ]; then
- copy_exec /lib/udev/firmware.agent
- fi
- if [ -e "/lib/firmware/${version}/${firmware}" ]; then
- copy_exec "/lib/firmware/${version}/${firmware}"
- else
- copy_exec "/lib/firmware/${firmware}"
- fi
- if [ "${verbose}" = "y" ]; then
- echo "Adding firmware ${firmware}"
- fi
- done
- done
- }
踩坑之路多回顾,不要在一个坑掉两次!
THINK TWICE,CODE ONCE!
【推荐】国内首个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帮你做增删改查!!