retpolanne blog

Your friendly programmer catgirl 🏳️‍⚧️😺

1 December 2023

Notes on coding a bare bones RISC-V OS

by Anne Macedo

I’m currently making a bare-bones operating system for RISC-V using Rust. These are a few notes for this project.

Current pipeline

I’ve built a docker image for toolchain with the tag sucymanbaravan/osdev-utils:riscv and it contains the toolchain including gdb.

To build and run it:

BSP=mangopi make clean
BSP=mangopi make qemu

To debug it:

docker exec -it `docker ps -a | grep qemu | awk '{print $1}'` riscv64-unknown-linux-gnu-gdb target/riscv64gc-unknown-none-elf/release/kernel

on gdb:

(gdb) target remote :1234
Remote debugging using :1234
(gdb) disass _start
Dump of assembler code for function _start:
   0x0000000080000000 <+0>:	csrr	t0,mhartid
   0x0000000080000004 <+4>:	bnez	t0,0x8000003a <_start+58>
(gdb) set print asm-demangle on
(gdb) info functions
All defined functions:

File library/core/src/any.rs:
201:	static fn core::any::{impl#0}::type_id<core::panic::panic_info::{impl#0}::internal_constructor::NoPayload>();

Rustup config

   default host triple: riscv64gc-unknown-linux-gnu
     default toolchain: nightly
               profile: default
  modify PATH variable: yes

However the rustc toolchain was built for RISC-V… shouldn’t it be built for cross compilation?

So I rerun rustup to x86_64 and

rustup target add riscv64gc-unknown-linux-gnu

Okay, so I understood: I need the toolchain! If I install with the riscv triple I’m not getting just the toolchain.

rustup toolchain install nightly-riscv64gc-unknown-linux-gnu

Still downloads the riscv non-cross-compile binary…

On the rust-gdb script:

# Run GDB with the additional arguments that load the pretty printers
# Set the environment variable `RUST_GDB` to overwrite the call to a
# different/specific command (defaults to `gdb`).
RUST_GDB="${RUST_GDB:-gdb}"

RUST_GDB=`which riscv64-unknown-linux-gnu-gdb` rust-gdb
RUST_GDB=`which riscv64-unknown-linux-gnu-gdb` rust-gdb target/riscv64gc-unknown-none-elf/release/kernel
RUST_GDB=`which riscv64-unknown-linux-gnu-gdb` rust-gdb target/riscv64gc-unknown-none-elf/debug/kernel

It seems that I was compiling as release, once I removed –release I got a debug binary :)

YAY

(gdb) l _start_rust
Python Exception <class 'ModuleNotFoundError'>: No module named 'gdb'
26	/// The Rust entry of the `kernel` binary.
27	///
28	/// The function is called from the assembly `_start` function.
29	#[no_mangle]
30	pub unsafe fn _start_rust() -> ! {
31	   crate::kernel_init()
32	}

Make it shorter (after adding stuff to dockerfile)

docker exec -it `docker ps -a | grep qemu | awk '{print $1}'` rust-gdb target/riscv64gc-unknown-none-elf/debug/kernel

Trying to fix the memory regions:

(gdb) info files
Symbols from "/work/tutorial/target/riscv64gc-unknown-none-elf/debug/kernel".
Remote target using gdb-specific protocol:
	`/work/tutorial/target/riscv64gc-unknown-none-elf/debug/kernel', file type elf64-littleriscv.
	Entry point: 0x80000000
	0x0000000000000000 - 0x0000000080000000 is .boot_core_stack
	0x0000000080000000 - 0x0000000080000eb4 is .text
	0x0000000080000eb8 - 0x0000000080001255 is .rodata
	0x0000000080001258 - 0x000000008000135c is .eh_frame
	0x0000000080001360 - 0x0000000080001360 is .bss
	0x0000000080001360 - 0x0000000080001361 is .sbss
	0x0000000080001368 - 0x0000000080001620 is .sdata
	While running this, GDB does not access memory from...
Local exec file:
	`/work/tutorial/target/riscv64gc-unknown-none-elf/debug/kernel', file type elf64-littleriscv.
	Entry point: 0x80000000
	0x0000000000000000 - 0x0000000080000000 is .boot_core_stack
	0x0000000080000000 - 0x0000000080000eb4 is .text
	0x0000000080000eb8 - 0x0000000080001255 is .rodata
	0x0000000080001258 - 0x000000008000135c is .eh_frame
	0x0000000080001360 - 0x0000000080001360 is .bss
	0x0000000080001360 - 0x0000000080001361 is .sbss
	0x0000000080001368 - 0x0000000080001620 is .sdata

.boot_core_stack seems to be in the wrong position, it should be after .sdata

References

[1] rust-mangopi-OS-tutorials-riscv

[2] rust-raspberrypi-OS-tutorials

[3] Hello, RISC-V and QEMU

[4] Operating Systems in Rust #1: Hello RISC-V

[5] The Adventures of OS - RISC-V OS using Rust

[6] RISC-V Bare Bones

[7] RISC-V support

tags: os-dev - riscv