制作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脚本。脚本中这几行正好可以解释这个疑问:

  1. L8:  
  2. CONFDIR="/etc/initramfs-tools"  
  3. ...  
  4. L208:  
  5. for x in "${CONFDIR}/modules" /usr/share/initramfs-tools/modules.d/*; do  
  6.     if [ -f "${x}" ]; then  
  7.         add_modules_from_file "${x}"  
  8.     fi  
  9. done  

脚本对/etc/initramfs-tools/modules等文件做add_modules_from_file操作,从函数名就可以看出,实现解析文件内容并向initrd.img添加模块的功能必定在这个函数中。

  1. add_modules_from_file()  
  2. {  
  3.     # Sanity check  
  4.     if [ ! -e "${1}" ]; then  
  5.         echo "W: add_modules_from_file: arg1='${1}' does not exist." >&2  
  6.         return  
  7.     fi  
  8.   
  9.     grep '^[^#]' ${1} | while read module args; do  
  10.         [ -n "$module" ] || continue  
  11.         force_load "${module}" "${args}"  
  12.     done  
  13. }  


add_modules_from_file接受一个参数,就是配置文件路径,就是for循环中的/etc/initramfs-tools/modules。通过grep逐行读取该文件中的内容(跳过#开始的注释内容),将模块的名字和参数分别读到module和args中,然后传递给force_load。比如/etc/initramfs-tools/modules中有一行内容是vmxnet3,那么在此就是以

  1. force_load vmxnet3  

的形式调用force_load脚本函数

  1. force_load()  
  2. {  
  3.         manual_add_modules ${@}  
  4.                 #将模块名和参数追加到initrd.img目录结构的conf/modules文件中  
  5.         echo "${@}" >>"${DESTDIR}/conf/modules"  
  6. }  

下面贴上manual_add_modules的脚本,之前遗漏了。他主要作用是按模块的名字获得模块所在的路径,并获得其依赖的固件,最后一并拷贝到initrd.img目录结构中

  1. manual_add_modules()  
  2. {  
  3.     local kmod firmware  
  4.     #以vmxnet3为例 运行modprobe --show-depends vmxnet3 --set-version=3.13.0-32-generic  
  5.     #输出insmod /lib/modules/3.13.0-32-generic/kernel/drivers/net/vmxnet3/vmxnet3.ko   
  6.       
  7.     #运行modprobe --show-depends vmxnet3 --set-version=3.13.0-32-generic|awk '/^insmod/ { print $2 }'  
  8.     #输出/lib/modules/3.13.0-32-generic/kernel/drivers/net/vmxnet3/vmxnet3.ko  
  9.     #这是搜索模块对应的驱动文件  
  10.     for kmod in $(modprobe --set-version="${version}" --ignore-install \  
  11.     --quiet --show-depends "${1}" | awk '/^insmod/ { print $2 }'); do  
  12.         # Prune duplicates  
  13.         #如果initrd.img中已经存在该驱动文件 就算了  
  14.         if [ -e "${DESTDIR}/${kmod}" ]; then  
  15.             continue  
  16.         fi  
  17.         #否则 连同目录结构一起拷过去  
  18.         mkdir -p "${DESTDIR}/$(dirname "${kmod}")"  
  19.         cp -pL "${kmod}" "${DESTDIR}/$(dirname "${kmod}")"  
  20.         if [ "${verbose}" = "y" ]; then  
  21.             echo "Adding module ${kmod}"  
  22.         fi  
  23.   
  24.         # Add required firmware  
  25.         #列出模块所依赖的farmware  
  26.         for firmware in $(modinfo -F firmware "${kmod}"); do  
  27.             if [ -e "${DESTDIR}/lib/firmware/${firmware}" ] \  
  28.             || [ -e "${DESTDIR}/lib/firmware/${version}/${firmware}" ]; then  
  29.                 continue  
  30.             fi  
  31.   
  32.             # Only print warning for missing fw of loaded module  
  33.             # or forced loaded module  
  34.             if [ ! -e "/lib/firmware/${firmware}" ] \  
  35.             && [ ! -e "/lib/firmware/${version}/${firmware}" ] ; then  
  36.                 # Only warn about missing firmware if  
  37.                 # /proc/modules exists  
  38.                 if [ ! -e /proc/modules ] ; then  
  39.                     continue  
  40.                 fi  
  41.   
  42.                 if grep -q "^$(basename "${kmod}" .ko)[[:space:]]" \  
  43.                 /proc/modules \  
  44.                 || grep -q "^$(basename "${kmod}" .ko)" \  
  45.                 "${CONFDIR}/modules"; then  
  46.                     echo "W: Possible missing firmware /lib/firmware/${firmware} for module $(basename ${kmod} .ko)" >&2  
  47.                 fi  
  48.                 continue  
  49.             fi  
  50.             #拷贝firmware到initrd.img目录结构中  
  51.             if [ ! -e "${DESTDIR}/lib/udev/firmware.agent" ] \  
  52.             && [ -e "/lib/udev/firmware.agent" ]; then  
  53.                 copy_exec /lib/udev/firmware.agent  
  54.             fi  
  55.   
  56.             if [ -e "/lib/firmware/${version}/${firmware}" ]; then  
  57.                 copy_exec "/lib/firmware/${version}/${firmware}"  
  58.             else  
  59.                 copy_exec "/lib/firmware/${firmware}"  
  60.             fi  
  61.             if [ "${verbose}" = "y" ]; then  
  62.                 echo "Adding firmware ${firmware}"  
  63.             fi  
  64.         done  
  65.     done  
  66. }  




posted @   愤怒的企鹅  阅读(1361)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示