Skip to content

Commit 1d8516e

Browse files
authored
Merge pull request #551 from hermit-os/ci-u-boot
feat(xtask): add support for U-Boot
2 parents d869a4a + fa12e31 commit 1d8516e

File tree

5 files changed

+141
-20
lines changed

5 files changed

+141
-20
lines changed

.github/workflows/ci.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ jobs:
4848
packages: qemu-system-x86
4949
flags: --accel --sudo
5050
- arch: aarch64
51-
packages: qemu-system-arm ipxe-qemu
51+
packages: qemu-system-arm ipxe-qemu u-boot-qemu u-boot-tools
5252
- arch: aarch64_be
53-
packages: qemu-system-arm ipxe-qemu
53+
packages: qemu-system-arm ipxe-qemu u-boot-qemu u-boot-tools
5454
- arch: riscv64
5555
packages: qemu-system-misc
5656
runs-on: ${{ (matrix.arch == 'aarch64' || matrix.arch == 'aarch64_be') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }}
5757
steps:
58-
- name: Install QEMU
58+
- name: Install Packages
5959
run: |
6060
sudo apt-get update
6161
sudo apt-get install --no-install-recommends ${{ matrix.packages }}
@@ -92,6 +92,10 @@ jobs:
9292
if: matrix.arch == 'aarch64' || matrix.arch == 'aarch64_be'
9393
- run: cargo xtask ci qemu ${{ matrix.flags }} --target ${{ matrix.arch }}-elf --release
9494
if: matrix.arch == 'aarch64' || matrix.arch == 'aarch64_be'
95+
- run: cargo xtask ci qemu ${{ matrix.flags }} --target ${{ matrix.arch }}-elf --u-boot
96+
if: matrix.arch == 'aarch64'
97+
- run: cargo xtask ci qemu ${{ matrix.flags }} --target ${{ matrix.arch }}-elf --u-boot --release
98+
if: matrix.arch == 'aarch64'
9599
- run: cargo xtask ci qemu ${{ matrix.flags }} --target ${{ matrix.arch }}-sbi
96100
if: matrix.arch == 'riscv64'
97101
- run: cargo xtask ci qemu ${{ matrix.flags }} --target ${{ matrix.arch }}-sbi --release

xtask/src/ci/qemu.rs

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ pub struct Qemu {
2424
#[arg(long)]
2525
microvm: bool,
2626

27+
/// Run with U-Boot.
28+
#[arg(long)]
29+
u_boot: bool,
30+
2731
#[command(flatten)]
2832
build: Build,
2933

@@ -51,17 +55,9 @@ impl Qemu {
5155
eprintln!("::endgroup::")
5256
}
5357

54-
let sh = crate::sh()?;
55-
56-
if self.build.target() == Target::X86_64Uefi {
57-
sh.create_dir("target/esp/efi/boot")?;
58-
sh.copy_file(self.build.dist_object(), "target/esp/efi/boot/bootx64.efi")?;
59-
sh.copy_file(
60-
self.build.ci_image(self.image.as_deref().unwrap()),
61-
"target/esp/efi/boot/hermit-app",
62-
)?;
63-
}
58+
self.prepare_image()?;
6459

60+
let sh = crate::sh()?;
6561
let target = self.build.target();
6662
let qemu = target.qemu();
6763
let qemu = env::var("QEMU").unwrap_or_else(|_| format!("qemu-system-{qemu}"));
@@ -82,6 +78,43 @@ impl Qemu {
8278
Ok(())
8379
}
8480

81+
fn prepare_image(&self) -> Result<()> {
82+
let sh = crate::sh()?;
83+
84+
match self.build.target() {
85+
Target::X86_64Uefi => {
86+
sh.create_dir("target/esp/efi/boot")?;
87+
sh.copy_file(self.build.dist_object(), "target/esp/efi/boot/bootx64.efi")?;
88+
sh.copy_file(
89+
self.build.ci_image(self.image.as_deref().unwrap()),
90+
"target/esp/efi/boot/hermit-app",
91+
)?;
92+
}
93+
Target::Aarch64Elf | Target::Aarch64BeElf if self.u_boot => {
94+
sh.create_dir("target/boot")?;
95+
sh.copy_file(self.build.dist_object(), "target/boot/hermit-loader")?;
96+
sh.copy_file(
97+
self.build.ci_image(self.image.as_deref().unwrap()),
98+
"target/boot/hermit-app",
99+
)?;
100+
101+
cmd!(
102+
sh,
103+
"mkimage -f xtask/src/ci/u-boot/boot.its target/boot/boot.scr"
104+
)
105+
.run()?;
106+
cmd!(
107+
sh,
108+
"mkimage -E -f xtask/src/ci/u-boot/hermit.its target/boot/hermit.fit"
109+
)
110+
.run()?;
111+
}
112+
_ => (),
113+
}
114+
115+
Ok(())
116+
}
117+
85118
fn machine_args(&self) -> Vec<String> {
86119
if self.microvm {
87120
let frequency = get_frequency();
@@ -193,13 +226,20 @@ impl Qemu {
193226
]
194227
};
195228
cpu_args.push("-semihosting".to_string());
196-
cpu_args.push("-device".to_string());
197-
cpu_args.push(format!(
198-
"guest-loader,addr=0x48000000,initrd={}",
199-
self.build
200-
.ci_image(self.image.as_deref().unwrap())
201-
.display()
202-
));
229+
if self.u_boot {
230+
cpu_args.push("-bios".to_string());
231+
cpu_args.push("/usr/lib/u-boot/qemu_arm64/u-boot.bin".to_string());
232+
cpu_args.push("-drive".to_string());
233+
cpu_args.push("format=raw,file=fat:rw:target/boot".to_string());
234+
} else {
235+
cpu_args.push("-device".to_string());
236+
cpu_args.push(format!(
237+
"guest-loader,addr=0x48000000,initrd={}",
238+
self.build
239+
.ci_image(self.image.as_deref().unwrap())
240+
.display()
241+
));
242+
}
203243
cpu_args
204244
}
205245
Target::Riscv64Sbi => {

xtask/src/ci/u-boot/boot.its

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/dts-v1/;
2+
3+
/ {
4+
description = "Script to boot Hermit on QEMU virt";
5+
6+
images {
7+
default = "script-1";
8+
9+
script-1 {
10+
data = /incbin/("./boot.txt");
11+
type = "script";
12+
compression = "none";
13+
hash {
14+
algo = "sha256";
15+
};
16+
};
17+
};
18+
};

xtask/src/ci/u-boot/boot.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
load virtio 0:1 ${loadaddr} /hermit.fit
2+
iminfo
3+
4+
fdt addr ${loadaddr}
5+
fdt get value hermit_load /images/ramdisk-1 load
6+
7+
fdt addr ${fdt_addr}
8+
fdt mknode /chosen module@${hermit_load}
9+
fdt set /chosen/module@${hermit_load} compatible "multiboot,module\0multiboot,ramdisk"
10+
fdt set /chosen/module@${hermit_load} reg <${hermit_load} 0>
11+
fdt print
12+
13+
bootm

xtask/src/ci/u-boot/hermit.its

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/dts-v1/;
2+
3+
/ {
4+
description = "Hermit FIT image";
5+
#address-cells = <1>;
6+
7+
images {
8+
kernel-1 {
9+
description = "Hermit Loader";
10+
data = /incbin/("../../../../target/boot/hermit-loader");
11+
type = "kernel";
12+
arch = "arm64";
13+
os = "elf";
14+
compression = "none";
15+
load = <0x41000000>;
16+
entry = <0x41000000>;
17+
hash {
18+
algo = "sha256";
19+
};
20+
};
21+
22+
ramdisk-1 {
23+
description = "Hermit Kernel";
24+
data = /incbin/("../../../../target/boot/hermit-app");
25+
type = "ramdisk";
26+
arch = "arm64";
27+
os = "elf";
28+
compression = "none";
29+
load = <0x48000000>;
30+
entry = <0x48000000>;
31+
hash {
32+
algo = "sha256";
33+
};
34+
};
35+
};
36+
37+
configurations {
38+
default = "conf-1";
39+
40+
conf-1 {
41+
description = "Boot Hermit Loader with Kernel as ramdisk";
42+
kernel = "kernel-1";
43+
ramdisk = "ramdisk-1";
44+
};
45+
};
46+
};

0 commit comments

Comments
 (0)