我正在 Ubuntu 下编译一个自定义内核,我遇到了我的内核似乎不知道在哪里寻找固件的问题。在 Ubuntu 8.04 下,固件与内核版本的绑定方式与驱动程序模块的绑定方式相同。例如,内核 2.6.24-24-generic 将其内核模块存储在:
/lib/modules/2.6.24-24-generic
及其固件:
/lib/firmware/2.6.24-24-generic
当我根据“ Alternate Build Method: The Old-Fashioned Debian Way ”编译 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,由 Intel 提供并由 Ubuntu 打包。我不相信它与特定的内核版本有任何实际联系。cmp
表明各个目录中的版本是相同的。
那么内核如何知道去哪里寻找固件呢?
更新
我找到了解决我遇到的确切问题的方法,但是它不再适用,因为 Ubuntu 已经消除/etc/hotplug.d
并且不再将其固件存储在/usr/lib/hotplug/firmware
.
更新2
更多的研究发现了更多的答案。在 92 版之前udev
,该程序firmware_helper
是加载固件的方式。从udev
93 开始,这个程序被一个名为 firmware.sh 的脚本取代,据我所知,它提供了相同的功能。这两个都将固件路径硬编码为/lib/firmware
. Ubuntu 似乎仍在使用/lib/udev/firmware_helper
二进制文件。
固件文件的名称firmware_helper
在环境变量$FIRMWARE
中传递给连接到路径/lib/firmware
并用于加载固件的环境变量。
加载固件的实际请求是由驱动程序(在我的例子中为 ipw2200)通过系统调用发出的:
request_firmware(..., "ipw2200-bss.fw", ...);
现在在驱动程序调用request_firmware
和firmware_helper
查看$FIRMWARE
环境变量之间的某个地方,内核包名称被添加到固件名称之前。
那么谁在做呢?