我正在Ubuntu下编译自定义内核,遇到的问题是我的内核似乎不知道在哪里查找固件。在Ubuntu 8.04中,固件与驱动程序模块一样与内核版本绑定。例如,内核2.6.24-24-generic将其内核模块存储在:
/lib/modules/2.6.24-24-generic
以及其固件在:
/lib/firmware/2.6.24-24-generic
当我按照“旧式 Debian 方法备选构建方法"编译 2.6.24-24-generic Ubuntu 内核时,我得到了适当的模块目录,所有设备都可以工作,除了那些需要固件的设备,比如我的英特尔无线网卡(ipw2200 模块)。
例如,内核日志显示,当 ipw2200 尝试加载固件时,控制固件加载的内核子系统无法找到它。
ipw2200: Detected Intel PRO/Wireless 2200BG Network Connection
ipw2200: ipw2200-bss.fw request_firmware failed: Reason -2
errno-base.h将其定义为:
#define ENOENT 2 /* No such file or directory */
(返回 ENOENT 的函数在其前面加上了减号。)
我尝试在 /lib/firmware 中创建一个符号链接,其中我的内核名称指向 2.6.24-24-generic 目录,但这导致相同的错误。这个固件是由英特尔提供的非 GPL 固件,由 Ubuntu 打包。我不认为它与特定的内核版本有任何实际关系。cmp
显示各个目录中的版本是相同的。
那么内核如何知道在哪里查找固件?
更新
我找到了这个解决方案来解决我遇到的确切问题,但由于 Ubuntu 已经删除了 /etc/hotplug.d
并且不再将其固件存储在 /usr/lib/hotplug/firmware
中,因此它不再起作用。
更新2
进行了更多的研究,找到了更多的答案。在 udev 版本 92 之前,程序 firmware_helper
是加载固件的方法。从 udev 93 开始,该程序被更换为名为 firmware.sh 的脚本,据我所知,它提供了相同的功能。这两个都将固件路径硬编码为 /lib/firmware
。Ubuntu 仍然似乎在使用 /lib/udev/firmware_helper
二进制文件。
$FIRMWARE
传递给firmware_helper
,并与路径/lib/firmware
连接在一起,用于加载固件。驱动程序(在我的情况下为ipw2200)通过系统调用进行实际的加载固件请求:
request_firmware(..., "ipw2200-bss.fw", ...);
现在,在驱动程序调用request_firmware
和firmware_helper
查看$FIRMWARE
环境变量之间的某个地方,内核包名称被添加到固件名称前面。
那么是谁在这样做呢?