@@ -12,6 +12,11 @@ pub fn build(b: *std.Build) void {
1212 const mz_dep = b .dependency ("microzig" , .{});
1313 const mb = MicroBuild .init (b , mz_dep ) orelse return ;
1414
15+ // Use GNU objcopy instead of LLVM objcopy to avoid 512MB binary issue.
16+ // LLVM objcopy includes LOAD segments for NOLOAD sections, causing the binary
17+ // to span from flash (0x0) to RAM (0x20000000) = 512MB of zeros.
18+ const gnu_objcopy = b .findProgram (&.{"riscv64-unknown-elf-objcopy" }, &.{}) catch null ;
19+
1520 const available_examples = [_ ]Example {
1621 // CH32V003
1722 .{ .target = mb .ports .ch32v .chips .ch32v003x4 , .name = "empty_ch32v003" , .file = "src/empty.zig" },
@@ -72,10 +77,21 @@ pub fn build(b: *std.Build) void {
7277 // and allows installing the firmware as a typical firmware file.
7378 //
7479 // This will also install into `$prefix/firmware` instead of `$prefix/bin`.
75- mb .install_firmware (fw , .{});
76-
77- // For debugging, we also always install the firmware as an ELF file
7880 mb .install_firmware (fw , .{ .format = .elf });
81+
82+ // Use GNU objcopy to create .bin files (avoids LLVM objcopy 512MB issue)
83+ if (gnu_objcopy ) | objcopy_path | {
84+ const bin_filename = b .fmt ("{s}.bin" , .{example .name });
85+ const objcopy_run = b .addSystemCommand (&.{objcopy_path });
86+ objcopy_run .addArgs (&.{ "-O" , "binary" });
87+ objcopy_run .addArtifactArg (fw .artifact );
88+ const bin_output = objcopy_run .addOutputFileArg (bin_filename );
89+ b .getInstallStep ().dependOn (& b .addInstallFileWithDir (
90+ bin_output ,
91+ .{ .custom = "firmware" },
92+ bin_filename ,
93+ ).step );
94+ }
7995 }
8096}
8197
0 commit comments