Linux添加新设备驱动对initrd的影响及相关技术疑问
嘿,作为Linux新手能挖到initrd和vmlinuz这些底层概念,说明你是真的在琢磨启动的原理,挺棒的!我来逐个给你解答这些问题:
1. initrd是怎么实现加载硬件模块、加快启动速度的?
首先得明确:vmlinuz是压缩后的内核镜像,但它不可能把所有硬件的驱动都编译进去(那样内核会大到离谱,而且大部分模块对特定机器来说根本没用)。initrd就是个临时的迷你根文件系统,内核启动后会先把它加载到内存里,作为过渡。
它的工作流程大概是这样:
- 内核启动后,先挂载initrd作为临时根,执行里面的
init脚本(这是initrd的核心) - 这个脚本会调用硬件检测工具(比如udev、modprobe的相关组件),扫描当前机器的硬件
- 找到需要的驱动模块后,从initrd里加载它们(因为initrd已经把当前机器必要的模块打包进去了)
- 等关键硬件(比如存储控制器、磁盘)的驱动都加载好,就能挂载真正的系统根分区,然后切换过去,完成启动
至于加速启动的原因:
- 它只打包当前机器必须的模块,不用内核在启动时遍历所有可能的驱动,节省了扫描时间
- 模块是提前打包成镜像的,加载时是一次性读取,比逐个从磁盘加载模块要快得多
2. initrd如何识别笔记本硬件所需的模块?
initrd里的工具靠硬件ID匹配来识别需要的模块:
- 启动时,工具会扫描PCI、USB等总线,读取每个硬件的厂商ID(Vendor ID)和设备ID(Device ID)
- 然后去模块数据库(比如
/lib/modules/$(uname -r)/modules.alias)里匹配,这个数据库里存着“哪些ID对应哪些驱动模块”的映射 - 找到对应的模块后,就用
modprobe加载它。比如指纹设备,会识别到它的USB/PCI ID,然后匹配到对应的指纹驱动模块(比如goodix_fp这类内核模块)
举个例子,你可以用lspci -nn或者lsusb -v查看自己机器的硬件ID,然后去modules.alias里搜,就能找到对应的模块名。
3. 同版本Ubuntu在有无指纹设备的两台笔记本上,initrd是否不同?
是的,肯定不同。
Ubuntu默认用update-initramfs工具生成initrd,这个工具会在生成时扫描当前机器的硬件,只把启动时必须的模块打包进去。有指纹设备的机器,initrd里会包含指纹驱动模块;没有的机器,这个模块就不会被打包进去。
甚至哪怕是同一台机器,换了硬件(比如加了新的SSD),重新生成的initrd也会和之前不一样,因为要加入新的存储驱动模块。
4. 添加新内核模块时,需要更新initrd吗?
分两种情况:
- 如果这个模块是启动阶段必须加载的(比如新的磁盘控制器驱动、网卡驱动,或者某些需要在挂载根分区前用到的硬件驱动):必须更新initrd!因为启动时内核只能从initrd里找这些模块,不更新的话,启动时会因为找不到驱动而卡住。
- 如果这个模块是系统启动后才需要的(比如蓝牙鼠标驱动、指纹识别的用户态辅助模块,平时用的时候才加载):不需要更新initrd,因为系统启动后,
modprobe可以直接从/lib/modules/$(uname -r)/目录里加载模块。
如果需要更新initrd,运行这个命令就行:
sudo update-initramfs -u
这个命令会重新生成当前内核对应的initrd镜像,把新的模块加进去。
内容的提问来源于stack exchange,提问作者Mahmoud Emam
相关产品推荐
相关产品推荐

