- Bootstraping rust runtime with QEMU -machine=virt (Which we shall call: virt)
- Reading the device tree. We just pull out what we need in a big horrible function.
- Basic Memory allocation with a fixed size heap.
- UART serial console. With println! support. Fallback to SBI putchar in case of early panic.
- Unit test framework.
- Timers using the monotonic
mtime
clock. - Reading RTC time.
- System reset/shutdown via SBI.
- Easy launching by going
cargo run
. (Assuming you have a toolchain and qemu)
- Paging.
- Good allocation of all the avalible memory.
- External interrupts. Yes the code seems to be there for UART interrupts. But it doesn't work.
Assming $SRC
is a directory
- Clone this repo as a subdirectory of
$SRC
:
$ git clone [email protected]:trissylegs/adeline-os.git "$SRC/kernel"
- Clone opensbi next to this repo:
$ git clone [email protected]:riscv-software-src/opensbi.git "$SRC/opensbi"
Ensure you have QEMU with RISC-V support. Checking:
$ qemu-system-riscv64 -version
QEMU emulator version 7.1.0
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
To Compile:
# There's no strict order. OpenSBI isn't a compile-time dependency.
$ make opensbi
$ cargo build
To run:
make run
or
cargo run
To debug open two terminals
# Terminal 1:
$ make run-gdb
# Terminal 2:
$ make attach-gdb
TODO
Notes:
- The brew tap for
riscv-gnu-toolchain
was outdated last I checked. - I'm manually compiling and building the risc-v tools from: https://github.com/riscv-collab/riscv-gnu-toolchain
- Just clone the repo. Setup your desintion with write permissions for your user. I put them in
/opt/riscv
. - The tools just need to be in your
$PATH
under names like:riscv64-unknown-elf-gcc
- The rust instructions for linux should be correct still for mac.
FIXME: I broke linux config making macos work :/
- Linux host (Maybe FreeBSD works)
- qemu-system-riscv64 (A riscv64 emulator)
- A gnu
riscv-elf-
toolchain. So can you do this:
$ riscv64-elf-gcc
riscv64-elf-gcc: fatal error: no input files
compilation terminated.
- Rust + Cargo with target
riscv64gc-unknown-none-elf
. To install with rustup run. (I think this is optional, but it doesn't hurt)
$ rustup target add riscv64gc-unknown-none-elf
- Optional:
riscv-elf-gdb
(For debugging)
- Make a directory for working with multiple repos.
$ mkdir adeline-os
$ cd adeline-os
- Checkout this repo
$ git checkout [email protected]:trissylegs/adeline-os.git
- Checkout OpenSBI.
$ git checkout [email protected]:riscv-software-src/opensbi.git
- Make opensbi
$ cd opensbi
$ make CROSS_COMPILE=riscv64-elf- PLATFORM=generic
- Go back to our repo
$ cd ../adeline-os
- Cargo run
$ cargo run
Should get something like this:
OpenSBI v1.0-5-g5d025eb
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
\____/| .__/ \___|_| |_|_____/|____/_____|
| |
|_|
Platform Name : riscv-virtio,qemu
...
Boot HART MEDELEG : 0x000000000000b109
Hello, world
heart: 0
device tree: 0x87000000
Sstatus {
uie: false
sie: false
upie: false
spie: false
spp: User
fs: Dirty
xs: Off
sum: false
mxr: false
sd: true
}
Sstatus {
usoft: false
ssoft: false
utimer: false
utimer: false
stimer: false
uext: false
sext: false
}
Stvec {
address: 80204000
mode: Some(Direct)
}
Bare
0
0
Base mapping not more details.
After doing above.
- Open two terminals in the root of this repos source.
- Launch qemu with kernel. It'll pause on the first instruction (should be at 0x1000)
$ make run-gdb
- Launch gdb atteched to remote session
$ make attach-gdb
- Set your breakpoints. Some good breakpoints:
break *0x80000000
Entrypoint for OpenSBI. You can also get here quickly by just usingstepi
.break sbi_trap_handler
. Entry point for SBI's trap handler. You'll get here when you do something wrong, make an SBI call, or when a timer goes off.break *0x80200000
. Entry for Supervisor mode. Assembly defined inentry.S
. Address hardcoded in linker.ldbreak kmain
. Rust entrypoint.