diff --git a/doc/raspi4b.txt b/doc/raspi4b.txt index 6db3cf31..9333769c 100644 --- a/doc/raspi4b.txt +++ b/doc/raspi4b.txt @@ -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 :initrd.tar -tftpboot ${loadaddr} :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 -bootelf -p -go ${kernel_addr_r} ${fdt_addr_r} +### If using DHCP +$ dhcp +### If not using DHCP +$ env set ipaddr +$ env set fdt_addr_r 0x11000000 +$ env set initrd_addr_r 0x04000000 +$ tftpboot ${initrd_addr_r} :initrd.tar +$ tftpboot ${loadaddr} :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}: ${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} diff --git a/doc/visionfive2.txt b/doc/visionfive2.txt index a5b2059c..d9b73d81 100644 --- a/doc/visionfive2.txt +++ b/doc/visionfive2.txt @@ -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 :initrd.img -# Load kernel -tftpboot ${loadaddr} :yggdrasil-kernel.bin -# Load dtb -load mmc 1:3 ${fdt_addr_r} dtbs/...-starfive/starfive/${fdtfile} -fdt resize -# Enter the kernel -booti ${loadaddr} 0x70000000: ${fdt_addr_r} +### If using DHCP +$ dhcp +### If not using DHCP +$ env set ipaddr +$ env set initrd_addr_r 0x70000000 +### [Optional] set some kernel cmdline params +$ env set bootargs "debug.serial-level=info" +$ tftpboot ${initrd_addr_r} :initrd.tar +$ tftpboot ${loadaddr} :kernel.bin +$ load mmc 1:3 ${fdt_addr_r} dtbs/...-starfive/starfive/${fdtfile} +$ fdt resize +$ booti ${loadaddr} ${initrd_addr_r}: ${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} diff --git a/etc/ld/arm/aarch64-unknown-raspi4b.ld b/etc/ld/arm/aarch64-unknown-raspi4b.ld index 4669e033..b16e11e8 100644 --- a/etc/ld/arm/aarch64-unknown-raspi4b.ld +++ b/etc/ld/arm/aarch64-unknown-raspi4b.ld @@ -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); }; diff --git a/etc/ld/riscv/riscv64-unknown-qemu.ld b/etc/ld/riscv/riscv64-unknown-qemu.ld index 93a86bf2..8a9547b2 100644 --- a/etc/ld/riscv/riscv64-unknown-qemu.ld +++ b/etc/ld/riscv/riscv64-unknown-qemu.ld @@ -55,4 +55,5 @@ SECTIONS { PROVIDE(__bss_size = __bss_end_phys - __bss_start_phys); PROVIDE(__kernel_end = .); + PROVIDE(__kernel_size = __kernel_end - __kernel_start); }; diff --git a/kernel/arch/aarch64/src/mem/mod.rs b/kernel/arch/aarch64/src/mem/mod.rs index 9b731cc1..578160bf 100644 --- a/kernel/arch/aarch64/src/mem/mod.rs +++ b/kernel/arch/aarch64/src/mem/mod.rs @@ -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::(KERNEL_VIRT_OFFSET + KERNEL_PHYS_BASE); diff --git a/kernel/src/arch/aarch64/boot/entry.S b/kernel/src/arch/aarch64/boot/entry.S index 9a754b2a..e94d3a6c 100644 --- a/kernel/src/arch/aarch64/boot/entry.S +++ b/kernel/src/arch/aarch64/boot/entry.S @@ -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 diff --git a/kernel/src/arch/riscv64/boot/entry.S b/kernel/src/arch/riscv64/boot/entry.S index 8150d5a1..e55d0f95 100644 --- a/kernel/src/arch/riscv64/boot/entry.S +++ b/kernel/src/arch/riscv64/boot/entry.S @@ -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 diff --git a/kernel/tools/gentables/src/main.rs b/kernel/tools/gentables/src/main.rs index 122d4d79..a51495ac 100644 --- a/kernel/tools/gentables/src/main.rs +++ b/kernel/tools/gentables/src/main.rs @@ -289,22 +289,6 @@ fn write_tables( Ok(()) } -fn write_image_header( - 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, table: HashMap, @@ -332,9 +316,6 @@ fn gentables(image: impl AsRef, symbol_out: impl AsRef) -> 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)?; }