【发布时间】:2010-10-31 07:25:54
【问题描述】:
我正在 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表示各个目录下的版本是一样的。
那么内核是如何知道去哪里寻找固件的呢?
更新
我找到了this solution 来解决我遇到的确切问题,但是它不再有效,因为 Ubuntu 已经消除了 /etc/hotplug.d 并且不再将其固件存储在 /usr/lib/hotplug/firmware 中。
更新2
更多的研究发现了更多的答案。在udev 的第92 版之前,程序firmware_helper 是加载固件的方式。从udev93 开始,这个程序被一个名为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 环境变量,内核包名称被添加到固件名称之前。
那么谁在做呢?
【问题讨论】:
-
有人可以添加评论,解释他们为什么投票结束这个问题吗?非常感谢您的反馈。
-
它被投票关闭,因为它“属于 serverfault.com”。由于问题不是关于编程,而是更多关于管理,这符合两个站点的使命宣言。
-
感谢您的反馈。我认为这是一个编程问题,因为它是在尝试构建自定义内核时遇到的问题。我想知道为什么有人会认为这与编程无关,尽管我想我有一些很好的猜测。
标签: linux-kernel linux-device-driver firmware