diff options
author | Himbeer <himbeer@disroot.org> | 2024-05-14 11:16:29 +0200 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-05-14 11:16:29 +0200 |
commit | 0223e24edc677c6cbd761b8705d8044f0598db1d (patch) | |
tree | 253e745a04e9f86944afa1d3a966a557a5620432 | |
parent | 6cf1d26dab3cdefeaa221a0e5499f87e0a2cc7eb (diff) |
doc: Add setup instructions for U-Boot and OpenSBI (qemu-virt64)
Fixes #13.
-rw-r--r-- | README.md | 138 |
1 files changed, 137 insertions, 1 deletions
@@ -18,7 +18,143 @@ for limited command-line or server usage. See the [project page](https://himbeerserver.de/md/srvre/kernel.md) for more information. -# Booting +# Building a bootable image + +## Boot flow + +This kernel is mainly developed for qemu-virt64 and the Lichee Pi 4A. +The latter uses the following boot flow: + +``` +~ M-mode ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|~ S-mode ~~~ ++------+ +------------+ +--------+ +---------+ +--------+ +| brom | --> | U-Boot SPL | --> | U-Boot | --> | OpenSBI | --> | Kernel | ++------+ +------------+ +--------+ +---------+ +--------+ +``` + +QEMU can be adapted to use this boot flow as well (the default is different). + +## Building the kernel + +Making a debug build of this kernel is straightforward: + +``` +zig build +``` + +You can also use any other Zig build mode, e.g. `-Doptimize=ReleaseFast`. + +This results in a `zig-out/bin/srvre_kernel.elf` file. +You may `strip(1)` this file if you want to. + +## Building OpenSBI + +Required dependencies: + +* riscv64-linux-gnu-gcc + +Clone the [OpenSBI repository](https://github.com/riscv-software-src/opensbi) +and run the following command: + +``` +make CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic FW_DYNAMIC=y -j $(nproc) all +``` + +This results in a `build/platform/generic/firmware/fw_dynamic.bin` file. +You might be able to use precompiled versions of this file from other sources. + +**Important:** The default fw_dynamic payload corrupts the device tree. +You can fix this by padding it with zeroes at the end: + +``` +for i in {1..8192}; do echo -e '\x00' >> build/platform/generic/firmware/fw_dynamic.bin; done +``` + +## Building U-Boot + +The boot flow is not supported by upstream U-Boot. +There are several T-Head-specific forks that implement it for the Linux kernel, +but none that support regular ELF binaries. +Therefore a custom fork of U-Boot is required. + +Clone the [U-Boot fork](https://codeberg.org/Himbeer/u-boot) +and run: + +``` +make qemu-riscv64_spl_defconfig +make -j$(nproc) menuconfig +``` + +This will bring up the build configuration tool. +Set the following options: + +* Device Drivers > Serial > Base address of UART (CONFIG_DEBUG_UART_BASE): 0x10000000 +* Device Drivers > Serial > Base address of UART for SPL (CONFIG_SPL_DEBUG_UART_BASE): 0x10000000 +* Device Drivers > Serial > Select which UART will provide the debug UART (CONFIG_DEBUG_UART_NS16550=y): ns16550 +* Device Drivers > Serial > Check if UART is enabled on output (CONFIG_DEBUG_UART_NS16550_CHECK_ENABLED): Yes +* General Setup > Support for multiprocessor (?): No +* RISC-V architecture > Symmetric Multi-Processing (CONFIG_SMP): No +* RISC-V architecture > Symmetric Multi-Processing in SPL (CONFIG_SPL_SMP): No +* RISC-V architecture > Run Mode (CONFIG_RISCV_MMODE=y): Machine +* RISC-V architecture > SPL Run Mode (?): Machine +* SPL configuration options > Support SPL loading and booting of Legacy images (CONFIG_SPL_LOAD_FIT): No +* SPL configuration options > Show more information when something goes wrong (CONFIG_SPL_SHOW_ERRORS): Yes +* SPL configuration options > Offset to which the SPL should be padded before appending the SPL payload (CONFIG_SPL_PAD_TO): 0x1200000 +* Boot options > Boot images > Flattened Image Tree (FIT) > Enable SPL loading U-Boot as a FIT (basic fitImage features) (CONFIG_SPL_LOAD_FIT): No +* Boot options > Boot images > Flattened Image Tree (FIT) > Enable SPL loading U-Boot as a FIT (full fitImage features) (?): No +* Boot options > bootcmd value (CONFIG_BOOTCOMMAND): "virtio scan; fatload virtio 0 0x8f000000 uImage; bootm 0x8f000000" +* CONFIG_SPL_OPENSBI=n + +Then exit and select 'yes' to save your changes. Next, build the binaries: + +``` +make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j $(nproc) u-boot-with-spl.bin +``` + +## Create multi-file kernel image + +Create a legacy U-Boot image: + +``` +/path/to/u-boot/tools/mkimage -A riscv -O elf -T multi -C none -a 0x80400000 -e 0x80400000 -n SRVRE -d /path/to/srvre_kernel.elf:/path/to/fw_dynamic.bin:/path/to/devicetree.dtb /path/to/output/uImage +``` + +Write this `uImage` file to the first, FAT32 (LBA) partition +on an MBR partitioned drive. You should now be able to boot QEMU: + +``` +qemu-system-riscv64 -M virt -m 2G -display none -serial stdio -bios /path/to/u-boot-with-spl.bin -drive file=/path/to/disk/image,if=virtio,media=disk,format=raw +``` + +### Extract QEMU device tree + +The default `arch/riscv/dts/qemu-virt64.dtb` tree is an image tree and doesn't help. +To extract the device tree, create an empty file on the disk image. +Then boot the VM as explained above but hit a key before it autoboots. +Run the following command in the U-Boot shell: + +``` +env print fdtcontroladdr +``` + +Then use the printed value like so (without the angle brackets): + +``` +fdt addr 0x<ENV_OUTPUT> +fdt header +``` + +You should now see a `totalsize` value. Take note of the hexadecimal notation +and save it to disk: + +``` +virtio scan +fatwrite virtio 0 0x<ENV_OUTPUT> <EMPTY_FILE_NAME> <HEX_TOTALSIZE> +``` + +You can now `poweroff` and build an image using the commands above. + +# Boot protocol The kernel expects to be loaded in S-mode with the following register values: |