我正在Ubuntu下编译一个自定义内核,遇到的问题是,我的内核似乎不知道在哪里查找固件。在Ubuntu8.04下,固件与内核版本的绑定方式与驱动模块相同。例如,内核2.6.24-24-泛型将其内核模块存储在:
/lib/modules/2.6.24-24-generic
及其固件如下:
/lib/firmware/2.6.24-24-generic
当我根据"交替构建方法:老式的Debian方法“编译2.6.24-24通用的Ubuntu内核时,我会得到适当的模块目录,除了需要固件的设备(如我的英特尔无线网卡(ipw2200模块))之外,我的所有设备都能工作。
例如,内核日志显示,当ipw2200试图加载固件时,控制固件加载的内核子系统无法找到它:
ipw2200: Detected Intel PRO/Wireless 2200BG Network Connection
ipw2200: ipw2200-bss.fw request_firmware failed: Reason -2
H将其定义为:
#define ENOENT 2 /* No such file or directory */
(返回ENOENT的函数在它前面放一个减号。)
我尝试在/lib/固件中创建一个符号链接,其中内核的名称指向2.6.24-24-泛型目录,但是这导致了同样的错误。这个固件是非GPL,由英特尔提供,由Ubuntu打包.我不相信它与特定的内核版本有任何实际的联系。cmp
显示各个目录中的版本是相同的。
那么内核如何知道在哪里查找固件呢?
更新
我发现了这个解决方案的确切问题,但是它不再起作用了,因为Ubuntu已经淘汰了/etc/hotplug.d
,并且不再将固件存储在/usr/lib/hotplug/firmware
中。
Update2
更多的研究发现了更多的答案。直到92版的udev
,程序firmware_helper
是固件加载的方式。从udev
93开始,这个程序被一个名为firmware.sh的脚本所取代,据我所知,它提供了相同的功能。这两种方法都硬编码到/lib/firmware
的固件路径。Ubuntu似乎仍然在使用/lib/udev/firmware_helper
二进制文件。
固件文件的名称在环境变量$FIRMWARE
中传递给$FIRMWARE
,该变量连接到路径/lib/firmware
并用于加载固件。
加载固件的实际请求是由驱动程序(在我的例子中是ipw2200)通过系统调用进行的:
request_firmware(..., "ipw2200-bss.fw", ...);
现在,在调用request_firmware
和firmware_helper
的驱动程序之间,在查看$FIRMWARE
环境变量时,内核包名称被放在固件名称的前面。
那是谁干的?
发布于 2010-06-10 07:04:55
哇,这是非常有用的信息,它引导我解决我的问题时,为一个需要固件的设备定制USB内核模块。
基本上,每个Ubuntu都带来了一个新的hal,sysfs,devfs,udev的重哈希,所以on...and的事情就会改变。事实上,我读到他们不再使用哈尔。
因此,让我们再一次进行逆向工程,以便它与最新的Ubuntu系统相关。
在Ubuntu (撰写本文时的最新版本)上,使用了/lib/udev/rules.d/50-firmware.rules
。该文件调用二进制/lib/udev/firmware
,其中发生了魔术。
清单:/lib/udev/rules.d es.d/50-固件。
# firmware-class requests, copies files into the kernel
SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware --firmware=$env{FIRMWARE} --devpath=$env{DEVPATH}"
魔法应该是这样的(源:http://lwn.net/Kernel/LDD3/):
loading
data
loading
并停止固件加载过程。loading
(向内核发送信号)如果您查看udev的udev-151/extras/firmware/firmware.c
源页面,即该固件/lib/udev/固件二进制文件的源代码,这正是所发生的事情。
摘录:清晰来源,UDEV-151/extras/固件/固件.c
util_strscpyl(datapath, sizeof(datapath), udev_get_sys_path(udev), devpath, "/data", NULL);
if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) {
err(udev, "error sending firmware '%s' to device\n", firmware);
set_loading(udev, loadpath, "-1");
rc = 4;
goto exit;
};
set_loading(udev, loadpath, "0");
此外,许多设备使用Intel HEX格式(包含校验和和等内容的文本文件) (wiki it I‘t’s‘t’t‘s’t‘s’t‘s(我没有声誉,也没有链接能力)。内核程序ihex2fw (从内核_ .HEX /lib/.HEX文件中的Makefile调用)将这些HEX文件转换成任意设计的二进制格式,然后由Linux内核使用request_ihex_firmware
来获取,因为他们认为在内核中读取文本文件是愚蠢的(这会减慢速度)。
发布于 2009-06-04 12:12:18
在当前的Linux系统上,这是通过udev
和firmware.agent
来处理的。
发布于 2013-02-26 09:59:13
Linux3.5.7 Gentoo,我也有同样的问题。已解决:
emerge ipw2200-firmware
然后转到/usr/src/linux
make menucofig
在设备驱动程序上,删除所有不需要的无线型驱动程序,将intel2200设置为模块并重新编译。
make
make modules_install
cp arch/x86/boot/bzImage /boot/kernel-yourdefault
https://stackoverflow.com/questions/950107
复制相似问题