boot: fix riscv64/aarch64 boot headers
This commit is contained in:
+26
-38
@@ -3,55 +3,43 @@
|
||||
|
||||
Booting Yggdrasil on Raspberry Pi 4B with u-boot:
|
||||
|
||||
1. Clone u-boot sources to some directory and checkout some
|
||||
stable branch. I've used v2024.10.
|
||||
2. Modify cmd/boot.c by replacing the do_go_exec function:
|
||||
1. Clone u-boot sources and build with rpi_4_defconfig
|
||||
|
||||
/* Allow ports to override the default behavior */
|
||||
__attribute__((weak))
|
||||
unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
void *entry_ptr = (void *) entry;
|
||||
ulong fdt_addr_r = 0;
|
||||
if (argc >= 2) {
|
||||
fdt_addr_r = hextoul(argv[1], NULL);
|
||||
}
|
||||
void (*func)(ulong) = entry_ptr;
|
||||
func(fdt_addr_r);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
3. make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 rpi_4_defconfig
|
||||
4. make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 -j
|
||||
5. Copy u-boot.bin into your Pi SD-card's boot partition.
|
||||
**NOTE** I assume you have all the bootloader parts in the boot partition already.
|
||||
If not, clone raspberry fw repo and copy the following files to the boot partition:
|
||||
* bootcode.bin
|
||||
* start4.elf
|
||||
* all the .dtb files (a bcm2711-rpi-4-b.dtb should be enough though)
|
||||
6. config.txt:
|
||||
|
||||
2. Copy u-boot.bin into the Pi's boot partition and edit the config.txt:
|
||||
enable_uart=1
|
||||
arm64_bit=1
|
||||
kernel=u-boot.bin
|
||||
|
||||
7. Compile the OS with `cargo xtask --arch=aarch64 --board=raspi4b --release`
|
||||
8. Copy the following files into some directory:
|
||||
* target/aarch64-unknown-raspi4b/release/yggdrasil-kernel
|
||||
3. Compile the OS with `cargo xtask --arch=aarch64 --board=raspi4b --release`
|
||||
4. Copy the following files into some directory:
|
||||
* target/aarch64-unknown-raspi4b/release/kernel.bin
|
||||
* userspace/target/aarch64-unknown-yggdrasil/release/initrd.tar
|
||||
9. cd into that directory and start a TFTP server of your choice. I used `uftpd`.
|
||||
5. cd into that directory and start a TFTP server of your choice. I used `uftpd`.
|
||||
|
||||
10. Connect an ethernet and serial to the Pi and run the following commands in u-boot shell:
|
||||
6. Connect an ethernet and serial to the Pi and run the following commands in u-boot shell:
|
||||
|
||||
tftpboot 0x04000000 <YOUR IP>:initrd.tar
|
||||
tftpboot ${loadaddr} <YOUR IP>:yggdrasil-kernel
|
||||
load mmc 0:1 ${fdt_addr_r} bcm2711-rpi-4-b.dtb
|
||||
fdt addr ${fdt_addr_r}
|
||||
fdt resize
|
||||
fdt memory 0x0 0x3C000000
|
||||
fdt chosen 0x04000000 <WHATEVER SIZE WAS PRINTED WHEN RUNNING THE FIRST COMMAND>
|
||||
bootelf -p
|
||||
go ${kernel_addr_r} ${fdt_addr_r}
|
||||
### If using DHCP
|
||||
$ dhcp
|
||||
### If not using DHCP
|
||||
$ env set ipaddr <RASPBERRY-IP-ADDR>
|
||||
$ env set fdt_addr_r 0x11000000
|
||||
$ env set initrd_addr_r 0x04000000
|
||||
$ tftpboot ${initrd_addr_r} <BUILD-MACHINE-IP-ADDR>:initrd.tar
|
||||
$ tftpboot ${loadaddr} <BUILD-MACHINE-IP-ADDR>:kernel.bin
|
||||
$ load mmc 0:1 ${fdt_addr_r} bcm2711-rpi-4-b.dtb
|
||||
$ fdt addr ${fdt_addr_r}
|
||||
$ fdt resize
|
||||
$ fdt memory 0x0 0x3C000000
|
||||
$ booti ${loadaddr} ${initrd_addr_r}:<SIZE-PRINTED-WHEN-LOADING-INITRD> ${fdt_addr_r}
|
||||
|
||||
11. Yggdrasil OS should start!
|
||||
###### Assuming BUILD-MACHINE-IP-ADDR is 13.0.0.1 and RASPBERRY-IP-ADDR is 13.0.0.2, here's
|
||||
###### a quick command for a development boot
|
||||
###### (FIXME when initrd gets larger than 64MiB)
|
||||
|
||||
env set ipaddr 13.0.0.2; env set fdt_addr_r 0x11000000; env set initrd_addr_r 0x04000000; tftpboot ${initrd_addr_r} 13.0.0.1:initrd.tar; tftpboot ${loadaddr} 13.0.0.1:kernel.bin; load mmc 0:1 ${fdt_addr_r} bcm2711-rpi-4-b.dtb; fdt addr ${fdt_addr_r}; fdt resize; fdt memory 0x0 0x3C000000; booti ${loadaddr} ${initrd_addr_r}:67108864 ${fdt_addr_r}
|
||||
|
||||
+19
-15
@@ -1,7 +1,6 @@
|
||||
Booting Yggdrasil OS on Starfive VisionFive 2 RISC-V board:
|
||||
|
||||
* TODO: proper format for initrd image
|
||||
* TODO: 0x70000000 can be replaced with a builtin var?
|
||||
|
||||
Prerequisites:
|
||||
|
||||
@@ -13,18 +12,23 @@ Steps:
|
||||
|
||||
1. Copy yggdrasil-kernel.bin and initrd.img into some directory and start a TFTP server there
|
||||
2. Connect to VF2's serial port, ethernet and enter u-boot
|
||||
3. Run the following commands:
|
||||
3. Run the following commands in u-boot:
|
||||
|
||||
# Get an IP address
|
||||
dhcp
|
||||
# [Optional] set some kernel cmdline params
|
||||
setenv bootargs "debug.serial-level=info"
|
||||
# Load initrd
|
||||
tftpboot 0x70000000 <your-ip-address>:initrd.img
|
||||
# Load kernel
|
||||
tftpboot ${loadaddr} <your-ip-address>:yggdrasil-kernel.bin
|
||||
# Load dtb
|
||||
load mmc 1:3 ${fdt_addr_r} dtbs/...-starfive/starfive/${fdtfile}
|
||||
fdt resize
|
||||
# Enter the kernel
|
||||
booti ${loadaddr} 0x70000000:<initrd-size> ${fdt_addr_r}
|
||||
### If using DHCP
|
||||
$ dhcp
|
||||
### If not using DHCP
|
||||
$ env set ipaddr <VF2-IP-ADDR>
|
||||
$ env set initrd_addr_r 0x70000000
|
||||
### [Optional] set some kernel cmdline params
|
||||
$ env set bootargs "debug.serial-level=info"
|
||||
$ tftpboot ${initrd_addr_r} <BUILD-MACHINE-IP-ADDR>:initrd.tar
|
||||
$ tftpboot ${loadaddr} <BUILD-MACHINE-IP-ADDR>:kernel.bin
|
||||
$ load mmc 1:3 ${fdt_addr_r} dtbs/...-starfive/starfive/${fdtfile}
|
||||
$ fdt resize
|
||||
$ booti ${loadaddr} ${initrd_addr_r}:<initrd-size> ${fdt_addr_r}
|
||||
|
||||
###### Assuming BUILD-MACHINE-IP-ADDR is 13.0.0.1 and VF2-IP-ADDR is 13.0.0.2, here's
|
||||
###### a quick command for a development boot
|
||||
###### (FIXME when initrd gets larger than 64MiB)
|
||||
|
||||
env set ipaddr 13.0.0.2; env set initrd_addr_r 0x70000000; tftpboot ${initrd_addr_r} 13.0.0.1:initrd.tar; tftpboot ${loadaddr} 13.0.0.1:kernel.bin; load mmc 1:3 ${fdt_addr_r} dtbs/...-starfive/starfive/${fdtfile}; fdt resize; booti ${loadaddr} ${initrd_addr_r}:67108864 ${fdt_addr_r}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
ENTRY(__aarch64_entry);
|
||||
|
||||
KERNEL_PHYS_BASE = 0x80000;
|
||||
KERNEL_PHYS_BASE = 0x200000;
|
||||
KERNEL_VIRT_OFFSET = 0xFFFFFF8000000000;
|
||||
|
||||
SECTIONS {
|
||||
@@ -52,4 +52,5 @@ SECTIONS {
|
||||
PROVIDE(__bss_size = __bss_end_phys - __bss_start_phys);
|
||||
|
||||
PROVIDE(__kernel_end = .);
|
||||
PROVIDE(__kernel_size = __kernel_end - __kernel_start);
|
||||
};
|
||||
|
||||
@@ -55,4 +55,5 @@ SECTIONS {
|
||||
PROVIDE(__bss_size = __bss_end_phys - __bss_start_phys);
|
||||
|
||||
PROVIDE(__kernel_end = .);
|
||||
PROVIDE(__kernel_size = __kernel_end - __kernel_start);
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@ const MAPPING_OFFSET: usize = KERNEL_VIRT_OFFSET;
|
||||
#[cfg(any(feature = "aarch64_board_virt", rust_analyzer))]
|
||||
const KERNEL_PHYS_BASE: usize = 0x40200000;
|
||||
#[cfg(any(feature = "aarch64_board_raspi4b", rust_analyzer))]
|
||||
const KERNEL_PHYS_BASE: usize = 0x80000;
|
||||
const KERNEL_PHYS_BASE: usize = 0x200000;
|
||||
|
||||
// Precomputed mappings
|
||||
const KERNEL_L1_INDEX: usize = page_index::<L1>(KERNEL_VIRT_OFFSET + KERNEL_PHYS_BASE);
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
__aarch64_entry:
|
||||
ccmp x18, #0, #0xd, pl // "MZ" magic
|
||||
b __aarch64_real_entry // Jump to real entry
|
||||
.quad 0 // Image load offset from start of RAM
|
||||
.quad 0x200000 // Image load offset from start of RAM
|
||||
.quad __kernel_size // Kernel size
|
||||
.quad 0 // Kernel flags
|
||||
.quad 0 // reserved
|
||||
|
||||
@@ -23,7 +23,7 @@ __rv64_entry:
|
||||
j __rv64_real_entry // Jump to real entry (if entered by non-Linux bootloader)
|
||||
.long 0
|
||||
.quad 0x200000 // Offset from RAM start
|
||||
.quad 2000000 // Image size TODO fill this by post-tooling
|
||||
.quad __kernel_size // Image size
|
||||
.quad 0 // Kernel flags
|
||||
.long 0x2 // Header version
|
||||
.long 0
|
||||
|
||||
@@ -289,22 +289,6 @@ fn write_tables<F: Write + Seek>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_image_header<F: Write + Seek>(
|
||||
file: &mut F,
|
||||
header: ImageHeader,
|
||||
image_size: u64,
|
||||
) -> Result<(), GenError> {
|
||||
match header {
|
||||
ImageHeader::Riscv(offset) => {
|
||||
let size_bytes = image_size.to_le_bytes();
|
||||
println!("Writing RISC-V image header: image_size={image_size}");
|
||||
file.seek(SeekFrom::Start(offset + 16))?;
|
||||
file.write_all(&size_bytes)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write_symbol_table(
|
||||
out: impl AsRef<Path>,
|
||||
table: HashMap<String, usize>,
|
||||
@@ -332,9 +316,6 @@ fn gentables(image: impl AsRef<Path>, symbol_out: impl AsRef<Path>) -> Result<()
|
||||
|
||||
let built = build_tables(&mut file)?;
|
||||
write_symbol_table(symbol_out, built.symbol_table)?;
|
||||
if let Some(header) = built.image_header {
|
||||
write_image_header(&mut file, header, built.image_size)?;
|
||||
}
|
||||
if let Some((tables, file_offset)) = built.tables {
|
||||
write_tables(file, file_offset, tables)?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user