您的位置:首页 > 运维架构 > Linux

制作initrd(3):/etc/initramfs-tools/modules配置文件分析

2015-11-26 22:45 543 查看
    这是前面:<制作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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux