Skip to content

feat(ostool): 支持 ELF/BIN FIT 生成 - #196

Open
MRNIU wants to merge 7 commits into
drivercraft:mainfrom
MRNIU:feat/elf-bin-fit
Open

MRNIU wants to merge 7 commits into
drivercraft:mainfrom
MRNIU:feat/elf-bin-fit

Conversation

@MRNIU

@MRNIU MRNIU commented Sep 24, 2026

Copy link
Copy Markdown
Member

支持生成包含 ELF 或 BIN 的 FIT 镜像;选择 BIN 时自动转换,无需手工处理。

  • 可选择 Linux 或 ELF OS,指定加载地址、入口地址、设备树和输出路径。
  • 地址支持自动获取或显式指定;无法可靠获取时明确报错。
  • 现有 U-Boot 默认生成行为保持兼容。

本 PR 提供生成能力,暂未新增命令或用户配置入口;入口由 PR 3 接入。

依赖 #193,仅包含其上的 FIT 增量。

MRNIU and others added 7 commits September 22, 2026 15:23
新增默认关闭的 artifacts.analysis 配置,复用 Rust 工具链 LLVM 和现有
artifact registry 生成反汇编、ELF 信息与符号列表。通过 object 解析架构、
入口、PT_LOAD 与可选 __executable_start,显式请求失败时返回具体错误。

分离原始 ELF 和运行时副本,避免 .elf 输入原地覆盖;添加 BIN 时保留
符号来源与调试产物登记,新构建则清理旧登记。完整 BuildConfig 接入
构建与运行入口,保留 Cargo 选择、hooks 和 Custom runner 配置读取顺序。
同步中英文 README 与公开 API 编译用例。

验证:devbox 原生格式化、workspace clippy/build/test 全部通过;
ostool all-targets/all-features clippy -D warnings 通过。新增实际 LLVM
产物、ELF metadata、状态更新和 CLI hook 回归测试。
x86_64 CI 命令已尝试,本地因缺少交叉 sysroot/libudev 与 C 编译器阻塞。

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
复用 tempfile 管理分析产物的临时文件和替换,移除手工暂存路径及重复的
runtime 来源状态。将完整配置运行入口收窄为 cargo_run_with_config,
Custom CLI 继续在构建完成后读取 runner 配置,并同步中英文说明。

删除重复成功/路径/默认配置断言和 ELF32 大端专项夹具,合并状态更新与
runner hooks 测试;保留 ELF 元数据、错误处理、strip 来源和构建兼容覆盖。

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
删除 metadata 层重复的非法 ELF 验证,保留分析入口的失败回归。
将 Custom build-only 状态断言并入重建测试,删除配置通用序列化
往返及可由其他检查推出的断言。简化无符号 ELF 与 PT_NOTE 夹具,
保留多段地址区分、符号定义状态和原始 ELF 来源验证。

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
移除独立构建与 CLI 分析验收文件、手工 ELF 测试夹具和假工具测试。
完整场景保留为本地验收,仓库仅新增短配置解析测试,并在已有
runtime/build 用例中验证源 ELF 不被覆写及旧分析登记失效。

移除只用于测试注入的 resolver 包装,直接调用既有 LLVM 定位函数。
产物生成、metadata 解析及错误处理行为保持一致。

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
新增 crate 内部 FIT format、OS、load/entry、FDT 与输出配置,继续复用
fitimage builder 与既有 runtime BIN 转换。原始 ELF 提供符号和入口,
runtime ELF 提供实际 payload;拒绝来源布局不一致和无效加载数据。

显式地址优先,auto load 优先采用 __executable_start;缺失符号时,
ELF 要求 PT_LOAD 的物理地址减文件偏移具有共同基址,BIN 按实际
file-backed allocated section 的 LMA 推导。合法零地址保留,歧义和
溢出明确报错。小幅补充既有 ELF metadata 的 section 信息,不新增解析器。

默认 U-Boot Linux FIT、LoongArch header 及 unsupported architecture
行为保持兼容。新配置输出原子替换以保护输入硬链接,空 BIN 明确失败。
用户入口留待后续接入,不增加 CLI、公开 Rust API 或配置文件字段。

新增真实 FIT 属性和提取字节检查、地址/来源/错误路径及配置往返测试。
devbox 原生 fmt、workspace clippy/build/test(630 项)以及 ostool
all-targets/all-features Clippy -D warnings 通过,FIT 聚焦 26 项通过。
x86_64 CI 三条命令已尝试,受容器交叉 C 编译器和 libudev sysroot 缺失阻塞。

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
保留 ELF/BIN 自动加载地址区别和配置往返两项短测试,
移除独立 FIT 集成测试文件、手写 ELF 和外部工具夹具。
生成逻辑保持不变,完整场景保留为本地验收。

devbox 格式检查、cargo test -p ostool 和严格 Clippy 通过。

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>
合入 upstream/main,保留 FIT 所需的 ELF section 元数据及现有解析行为。

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Niu Zhihong <zhihong@nzhnb.com>

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查结论

本 PR 新增 crate-private FitConfig 与 ELF 元数据解析,支持生成 ELF/BIN FIT、自动或显式设置 load/entry、可选 FDT 和输出路径;旧的 Linux U-Boot FIT 生成路径仍保留,且 PR 明确暂不新增 CLI 或用户配置入口。变更主要影响后续 boot-prepare 调用方,不改变当前默认 U-Boot 流程。

验证与上下文

  • GitHub check check (stable, x86_64-unknown-linux-gnu) 在目标 head f2bcdaaa73422520483acd8ba3b8fc1f80f91a41 上成功。
  • git diff --check origin/main...HEAD 通过,HEAD 与审查目标一致。
  • 本地 cargo fmt --check、cargo clippy --manifest-path ostool/Cargo.toml --all-features -- -D warnings 和 cargo test --manifest-path ostool/Cargo.toml --all-features 均因审查环境没有 cargo(退出码 127)未能运行;这不是 PR 代码导致的失败。
  • 当前 PR 没有既有 review、review comment 或 issue comment 需要处理。相近的 PR #193 是本 PR 声明的依赖,相关的 FIT/boot 边界重构 PR #123 仅作为实现模式参考。

需要修复的问题

  1. 配置化 BIN 路径没有复用 LoongArch Linux 镜像头部的入口地址换算,见行内评论。对于带 MZ 头的原始 LoongArch Linux BIN,FIT entry 必须按镜像头部相对偏移计算。
  2. BIN 自动 entry 直接使用 ELF e_entry,但 BIN load base 按 PT_LOAD.p_paddr/section LMA 推导;VMA 与 LMA 不同的合法 ELF 会被加载到一个地址却跳到另一个地址,见行内评论。

这两项都会导致生成的 FIT 在目标设备上无法正确启动。当前新增测试覆盖了地址解析的简单合成数据和旧生成路径,但没有覆盖 configured BIN/LoongArch 或 VMA/LMA 不同的 ELF;实际 U-Boot/硬件启动也未在本次环境验证。

Powered by gpt-5.6-luna

Comment thread ostool/src/boot/fit.rs
output_path: Some(temporary.path().to_path_buf()),
},
kernel_data,
entry,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里把配置解析出的 entry 直接传给 write_fit_image,绕过了旧路径 generate_fit_image 中针对 LoongArch Linux 镜像头部调用的 resolve_kernel_entry_addr。对带 MZ 头的原始 LoongArch Linux BIN,FIT entry 应为 kernel_load_addr + (image_entry - image_load);自动配置当前会保留 ELF entry,可能导致设备跳到错误地址。请对自动 BIN/Linux entry 复用该换算,同时保留显式 entry。

};
let entry = match self.entry {
FitAddress::Explicit(address) => address,
FitAddress::Auto => metadata.entry,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

当 format=Bin 且 entry=Auto 时,这里直接返回 ELF 的 e_entry(虚拟地址);但同一配置的 BIN load base 是按 section LMA/PT_LOAD.p_paddr 推导的。对于 VMA 与 LMA 不同的合法 ELF,FIT 会把 BIN 加载到物理地址却跳到虚拟地址。请通过匹配的 PT_LOAD 将 entry 映射到 raw BIN 的 LMA 偏移,并补充 VMA/LMA 不同的测试。

@ZR233 ZR233 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

当前 PR 只增加 crate 内部的 FIT 配置和生成入口;.build.toml、.uboot.toml 以及既有 U-Boot runner 的配置解析与调用点均未改动,旧配置仍走原来的 Linux FIT 生成路径。CI 通过证明了现有检查通过,但新增的 generate_configured_fit 尚未被用户入口调用,不能据此认定 ELF/BIN 新路径已经可启动。

请先修复下面两处地址语义问题,并增加从真实 ELF 生成 FIT、检查 FIT 属性与 payload 的回归验证。当前已有审查指出 LoongArch 及 BIN entry 的问题;这里的两处是额外发现。

后续接入用户配置时,建议在父配置使用可选字段,以“未填写继续走旧 generate_fit_image、显式填写才使用新生成路径”为语义。不要仅凭 FitConfig 的字段默认值切换旧流程:Auto 地址和空 FDT 可能覆盖旧的 kernel_load_addr、dtb_file。若字段放入 .uboot.toml,还需同步 UbootConfigWire 的反序列化;若板卡流程也要使用,需同步 .board.toml 到 UbootConfig 的映射。

};
let entry = match self.entry {
FitAddress::Explicit(address) => address,
FitAddress::Auto => metadata.entry,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] 对 os = "elf"、format = "elf",这里的 metadata.entry 是 ELF 可执行入口,但 U-Boot 的 bootm ELF 分支会将 FIT entry 作为 bootelf() 的输入地址,而 bootelf() 需要的是内存中 ELF 文件头地址。FIT payload 加载在 load,两者通常不同,因此镜像生成成功后仍无法由该分支启动。请按 ELF 文件头所在地址设置或校验 FIT entry,并用实际 ELF/FIT 验证。os = "elf" 还依赖目标 U-Boot 启用 CONFIG_BOOTM_ELF;当前允许它与默认 format = "bin" 组合,也应拒绝或定义可启动的语义。参见 https://github.com/u-boot/u-boot/blob/master/boot/bootm_os.c#L372-L393 和 https://github.com/u-boot/u-boot/blob/master/cmd/elf.c#L24-L32。

FitAddress::Explicit(address) => address,
FitAddress::Auto => match metadata.executable_start {
// The linker-provided origin describes the selected project's image base.
Some(address) => address,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] __executable_start 是 ELF 符号的虚拟地址;由 llvm-objcopy -O binary 生成的 BIN 则按实际可加载 section 的物理加载地址排列。若 ELF 的 VMA 与 LMA 不同,这里会绕过下面的 bin_load_base(),把虚拟地址写进 FIT load,导致 BIN 装载到错误地址。请对 BIN 优先按 section 的 LMA 推导;只有证实符号与该地址一致时才采用符号,无法确定时要求显式 load。建议用 VMA ≠ LMA 的 ELF 回归这一分支。

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants