ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Linux 内核中 Opera DVB-S1 USB-Box 固件提取与加载全解:从 get_dvb_firmware 到 dvb-usb 驱动

Linux 内核中 Opera DVB-S1 USB-Box 固件提取与加载全解:从 get_dvb_firmware 到 dvb-usb 驱动 Linux 内核中 Opera DVB-S1 USB-Box 固件提取与加载全解从 get_dvb_firmware 到 dvb-usb 驱动【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux本文围绕 Linux 内核官方文档 opera-firmware.rst 展开完整讲解 Opera DVB-S1 USB 机顶盒Opera DVB-S1 USB-Box的固件提取流程如何将 Windows 驱动中的 .sys 文件转换为内核可加载的 .fw 固件并结合 scripts/get_dvb_firmware 提取脚本与 opera1.c 驱动源码深入解析 FPGA/USB 控制器固件在内核中的下载与重启机制。读完本文你将掌握该设备固件获取的每一步操作、脚本内部的偏移量提取与 MD5 校验逻辑以及内核驱动 probe 阶段加载固件的完整调用链。一、背景为什么需要手动提取固件Opera DVB-S1 USB-Box 是一款通过 USB 接口接入的卫星DVB-S接收设备其核心由 Cypress FX2 USB 控制器与 FPGA 组成。设备固件并不随 Linux 内核发行而是封装在厂商提供的 Windows 驱动文件中。内核文档 Documentation/admin-guide/media/opera-firmware.rst作者 Marco Gittler给出的结论是需要把 Windows 驱动盘中的两个文件2830SCap2.sys2830SLoad2.sys复制到执行提取命令的当前目录在内核源码根目录运行提取脚本scripts/get_dvb_firmware opera1提取完成后会得到两个固件文件dvb-usb-opera-01.fwdvb-usb-opera1-fpga-01.fw将这两个文件复制到/lib/firmware/之后只要内核配置启用了固件加载firmware loading并且系统正在运行 hotplug如 udev驱动即可自动加载固件。这条流程的本质是2830SLoad2.sys中内嵌了运行在 FX2 USB 控制器 CPU 上的引导/加载固件2830SCap2.sys中内嵌了 FPGA 位流bitstream。提取脚本负责按精确的偏移量把这两段数据切出来、去除填充零、重组协议头并做完整性校验。二、准备工作依赖工具与内核配置2.1 依赖的用户态工具阅读 scripts/get_dvb_firmware 中的checkstandard()子程序第 809–819 行可知opera1 提取路径会先检查三个命令是否存在缺失时直接die报错命令用途脚本中的检查位置unzip解压压缩包opera1 路径不实际下载但统一做前置检查scripts/get_dvb_firmwaremd5sum对提取结果做 MD5 校验scripts/get_dvb_firmwarewget其他设备固件的下载opera1 不需要联网但同样被检查scripts/get_dvb_firmware因此执行前请先确认which unzip md5sum wget均可用。2.2 内核侧配置Opera1 的驱动由 Kconfig 选项DVB_USB_OPERA1控制定义于 drivers/media/usb/dvb-usb/Kconfigconfig DVB_USB_OPERA1 tristate Opera1 DVB-S USB2.0 receiver depends on DVB_USB select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT即在make menuconfig路径Media support → Multimedia support → DVB support → DVB USB devices下选择 “Opera1 DVB-S USB2.0 receiver”该选项依赖DVB_USB框架并自动选择 STV0299 解调器子驱动drivers/media/usb/dvb-usb/opera1.c 中opera1_stv0299_config通过stv0299_attach挂接。编译入口在 drivers/media/usb/dvb-usb/Makefiledvb-usb-opera-objs : opera1.o obj-$(CONFIG_DVB_USB_OPERA1) dvb-usb-opera.o文档中提到的“内核配置启用固件加载”即常规内核的CONFIG_FW_LOADER一类选项“hotplug running”指 udev 等机制能在request_firmware()触发固件缺失事件时把/lib/firmware/中的文件回传给内核。三、完整操作步骤步骤 1准备源文件把 Windows 驱动光盘文档中称 windriver disk里的2830SCap2.sys与2830SLoad2.sys拷贝到任意工作目录例如/root/opera-fw/。步骤 2运行提取脚本在内核源码树根目录执行scripts/get_dvb_firmware opera1脚本的参数匹配逻辑见 scripts/get_dvb_firmware参数必须恰好 1 个且必须命中components列表中的组件名opera1定义于第 15 行命中后以eval调用同名子程序opera1。成功后脚本向 stderr 打印Firmware(s) dvb-usb-opera1-fpga-01.fw,dvb-usb-opera-01.fw extracted successfully. Now copy it(them) to either /usr/lib/hotplug/firmware or /lib/firmware (depending on configuration of firmware hotplug).注意脚本输出的目标目录有两种/usr/lib/hotplug/firmware或/lib/firmware取决于系统的固件热插拔udev/uevent配置现代发行版通常是/lib/firmware与官方文档的建议一致。步骤 3安装固件cp dvb-usb-opera-01.fw dvb-usb-opera1-fpga-01.fw /lib/firmware/步骤 4加载驱动并验证插入设备后可观察内核日志确认固件下载过程驱动在 opera1_xilinx_load_firmware 中打印start downloading fpga firmware ...dmesg | grep -i opera ls /sys/class/dvb/若固件缺失驱动会打印如下错误源码见 opera1.c 第 458 行其中已经明示了本文使用的提取工具did not find the firmware file dvb-usb-opera1-fpga-01.fw. You can use kernel_dir/scripts/get_dvb_firmware to get the firmware四、提取脚本内部机制解析opera1 子程序opera1 子程序第 205–243 行是整个提取流程的核心其处理步骤可以拆解为四步。4.1 按偏移量切出两段数据脚本调用 extract() 子程序以 2048 字节块循环sysseek/sysread/syswrite数据不足即报 “Ran out of data”从两个 .sys 文件中按硬编码偏移提取extract(2830SCap2.sys, 0x62e8, 55024, $tmpdir/opera1-fpga.fw); extract(2830SLoad2.sys,0x3178,0x3685-0x3178,$tmpdir/fw1part1); extract(2830SLoad2.sys,0x0980,0x3150-0x0980,$tmpdir/fw1part2);从2830SCap2.sys偏移0x62e8处取出 55024 字节作为 FPGA 位流即最终的dvb-usb-opera1-fpga-01.fw从2830SLoad2.sys偏移0x3178长 0x50D 字节与0x0980长 0x27D0 字节分别取出加载固件的两段fw1part1、fw1part2。4.2 delzero去除填充零Windows 驱动中的数据段按 22 字节的记录块存放首字节为长度其后为数据中间以零填充。delzero() 按 22 字节读入一块依据首字节长度ord(substr($buf,0,1))只保留有效载荷第 1 字节长度字段 其后len3字节并追加 1 个0x00分隔从而得到去除填充后的fw1part1-1与fw1part2-1。4.3 MD5 完整性校验脚本对三段提取产物逐一执行 verify()内部调用md5sum并比对硬编码摘要校验值来自脚本源码文件期望 MD5fw1part1-15e0909858fdf0b5b09ad48b9fe622e70fw1part2-1d6e146f321427e931df2c6fcadac37a1opera1-fpga.fw0f8133f5e9051f5f3c1928f7e5a1b07d任一摘要不匹配即报 “Hash of extracted file does not match!” 并终止——这说明你手里的 .sys 文件版本与脚本预期的 windriver 版本不一致需更换对应版本的驱动文件。4.4 重组协议头生成 dvb-usb-opera-01.fwopera1 子程序的后半部分向opera.fw写入一系列 6 字节的 RES/DAT 控制字再交替追加两段固件数据my $RES1\x01\x92\x7f\x00\x01\x00; my $RES0\x01\x92\x7f\x00\x00\x00; my $DAT1\x01\x00\xe6\x00\x01\x00; my $DAT0\x01\x00\xe6\x00\x00\x00; # 写入顺序RES1 DAT1 RES1 DAT1 [fw1part1-1] RES0 DAT0 # RES1 DAT1 [fw1part2-1] RES1 DAT1 RES0 DAT0从结构看RES字0x0192请求/寄存器字末字节 1/0 区分两种状态与DAT字0x0100数据字构成主机侧的帧协议DATA段之间用RES0/DAT0收尾。最后两个成品文件被拷贝出临时目录copy($tmpdir/opera1-fpga.fw, dvb-usb-opera1-fpga-01.fw)copy($tmpdir/opera.fw, dvb-usb-opera-01.fw)临时目录使用tempdir(DIR /tmp, CLEANUP 0)创建见 第 206 行提取成功后不会自动清理排错时可以直接检查其中的中间产物。五、内核驱动侧probe 阶段如何加载这两个固件提取出的两个文件由 drivers/media/usb/dvb-usb/opera1.c 驱动分别消费二者时机不同5.1 冷/热双状态匹配驱动定义了两个 USB 设备匹配项opera1_tablestatic const struct usb_device_id opera1_table[] { DVB_USB_DEV(CYPRESS, CYPRESS_OPERA1_COLD), DVB_USB_DEV(OPERA1, OPERA1_WARM), { } };设备刚上电、未加载固件时呈现的是 Cypress FX2 默认描述符COLD 状态固件注入后控制器 CPU 重启设备切换为厂商自定义的 VID/PIDWARM 状态。设备描述在 opera1_properties.devices 中同时登记冷、热两张描述符名字为 “Opera1 DVB-S USB2.0”。5.2 FPGA 固件下载opera1_probe 的第一道工序opera1_probe() 在进入通用dvb_usb_device_init()之前先判断设备是否处于 WARM 状态USB_PID_OPERA1_WARMUSB_VID_OPERA1若是则调用opera1_xilinx_load_firmware(udev, dvb-usb-opera1-fpga-01.fw)opera1_xilinx_load_firmware() 的完整流程request_firmware(fw, filename, dev-dev)经固件加载框架读取/lib/firmware/dvb-usb-opera1-fpga-01.fw失败即返回错误并提示用scripts/get_dvb_firmware获取通过 vendor 控制请求0xbc/0x00读回一个状态字节testval仅当testval ! 0x67时才执行真正的下载从源码结构看0x67是 FPGA 已就绪的标记值可推断该检查用于跳过重复刷写发送0xbc/0xaa命令清除 FPGA以每块最多40 字节fpgasize40末块取剩余长度循环调用opera1_xilinx_rw()用 vendor 请求OPERA_WRITE_FX2 (0xbb)把位流分片写入全部写完后发送0xa0/0xe600命令重启 USB 控制器 CPU注释即 “restart the CPU”任一环节失败返回-EINVAL导致 probe 失败。5.3 USB 控制器固件dvb_usb_device_init 内部加载第二个固件dvb-usb-opera-01.fw声明在 opera1_properties.firmware 字段static struct dvb_usb_device_properties opera1_properties { .caps DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl CYPRESS_FX2, .firmware dvb-usb-opera-01.fw, ...由 dvb-usb 框架在dvb_usb_device_init()probe 第 566 行 调用中统一经request_firmware加载即文档所述“驱动可以加载固件前提是内核启用固件加载且 hotplug 正常工作”。5.4 固件加载后的硬件行为佐证两个固件的分工固件就绪后驱动的全部业务都建立在两块“固件化”硬件之上I2C 总线模拟opera1_usb_i2c_msgxfer() 把 I2C 地址映射为 USB vendor 控制请求如地址0xb600/0xb601映射 13V/18V LNB 电压切换0xb1a6映射流控制0xb880读遥控再经 opera1_xilinx_rw() 走usb_control_msg下发——这些寄存器行为由 FPGA 位流dvb-usb-opera1-fpga-01.fw实现调谐链路STV0299 解调器opera1_stv0299_configI2C 地址0xd01DVB_PLL_OPERA1PLL 调谐器opera1_tuner_attach数据通路MPEG-TS 经 bulk 端点0x82、10 条 4096 字节 URB 环回传stream 配置硬件 PID 过滤器最多 252 个。这些细节从侧面印证opera-01.fw决定控制器“怎么跑”opera1-fpga-01.fw决定 FPGA“怎么接”两者缺一设备都无法工作。六、调试与常见问题6.1 驱动调试参数驱动导出debug模块参数opera1.c 第 36–40 行位含义可直接用于定位固件相关异常set debugging level (1info, xfer2, pll4, ts8, err16, rc32, fw64 (or-able))例如modprobe dvb-usb-opera debug65infofw即可观察固件下载相关日志。6.2 常见失败场景对照现象脚本/驱动中的对应逻辑处理建议This firmware requires the unzip/md5sum/wget commandcheckstandard() 前置检查安装缺失工具后重跑Hash of extracted file does not match!verify() MD5 比对失败更换为脚本预期版本的2830SCap2.sys/2830SLoad2.sysRan out of dataextract() 偏移越界同上源文件版本不符did not find the firmware file dvb-usb-opera1-fpga-01.fwopera1.c 第 457–459 行request_firmware失败确认固件已放入/lib/firmware/且系统启用固件加载与 udev 热插拔probe 直接返回-EINVALopera1_probe 中 FPGA 固件加载失败或dvb_usb_device_init失败结合dmesg与debug64日志判断是 FPGA 分片写入还是 CPU 重启失败七、小结Opera DVB-S1 USB-Box 的固件支持是 Linux 内核“从闭源 Windows 驱动中提取固件”这一经典模式的典型样本文档 Documentation/admin-guide/media/opera-firmware.rst 给出两步操作流程拷贝两个 .sys 文件 → 运行scripts/get_dvb_firmware opera1→ 放入/lib/firmware/而 scripts/get_dvb_firmware 内部的偏移提取、delzero 去填充、MD5 校验与协议头重组保证了固件的确定性opera1.c 则在 probe 阶段经 vendor 控制消息完成 FPGA 位流分片写入与控制器 CPU 重启最终由 dvb-usb 框架统一加载 USB 控制器固件。理解了这条从脚本到驱动的完整链路也可以作为排查其他 DVB 设备固件问题的参考范式。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表