RISC-V Bare Bones: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
m update source tags to syntaxhighlight
 
(9 intermediate revisions by 7 users not shown)
Line 1:
{{ stub }}
 
'''THIS TUTORIAL IS LITTERED WITH BROKEN AND INCOMPATIBLE CODE. DO NOT USE.'''
 
 
RISC-V is a instruction set architecture, fully opensource. The ISA has a bunch of extensions, in this tutorial we will assume that imad are available.
Line 14 ⟶ 11:
The thing we will make here is a simple serial port output/reader.
 
<sourcesyntaxhighlight lang="c">
#include <stdint.h>
#include <stddef.h>
Line 20 ⟶ 17:
unsigned char * uart = (unsigned char *)0x10000000;
void putchar(char c) {
while(*(uart+))
*uart = c;
return;
Line 41 ⟶ 37:
return;
}
</syntaxhighlight>
</source>
 
This will print a simple "Hello world!" and a newline following, after that it will echo any input given to the serial port.
Line 48 ⟶ 44:
Be wary we are just setting up stack and jumping into kernel. It's the kernel's job to set up IRQs and other system stuff
 
<sourcesyntaxhighlight lang="asm">
.section .init
 
Line 75 ⟶ 71:
sd zero, (t5)
addi t5, t5, 8
bgeubltu t5, t6, bss_clear
la t0, kmain
Line 87 ⟶ 83:
.end
 
</syntaxhighlight>
</source>
 
Take in account that you need to implement a type of locking if you want to support SMP, and implement a trampoline or a jail for the CPUs. Be wary that we haven't enabled interrupts just yet and any return from kmain will result in invalid opcodes being executed.
Line 95 ⟶ 91:
We need to specify where our kernel will be loaded at. For this example we will use the start of the RAM as our load address.
 
<sourcesyntaxhighlight lang="c">
ENTRY(start);
Line 122 ⟶ 118:
}
}
</syntaxhighlight>
</source>
 
== Final ==
 
The process is pretty straightforward:
<sourcesyntaxhighlight lang="bash">
riscv64-elf-gcc -Wall -Wextra -c -mcmodel=medany kernel.c -o kernel.o -ffreestanding
riscv64-elf-as -c entry.S -o entry.o
riscv64-elf-ld -T linker.ld -lgcc -nostdlib kernel.o entry.o -o kernel.elf
</syntaxhighlight>
</source>
 
Once this is done, the kernel can be run with the following:
<sourcesyntaxhighlight lang="bash">
qemu-system-riscv64 -machine virt -bios none -kernel kernel.elf -serial mon:stdio
</syntaxhighlight>
</source>
 
You will promptly see a terminal with the "Hello world!" and you can "write stuff" to it. A serial terminal is very "boring", but you still have a lot at your disposal, you have a PLIC, a CLIC and a bunch of opportunities to learn PCI internals.
Line 142 ⟶ 138:
== Going further ==
* Store input somewhere for later processing (i.e: "echo" command)
* Implement SMP support, for now our basic bootloaderkernel will crash on any multicore system
* QEMU will give FDT in register a1. Use libfdt to parse the tree to avoid nightrames
* Implement a heap
Line 153 ⟶ 149:
* [[PCI Express]]
* [[HiFive-1 Bare Bones]]
* [[RISC-V_Meaty_Skeleton_with_QEMU_virt_board|RISC-V Meaty Skeleton with QEMU virt board]]
* [https://msyksphinz-self.github.io/riscv-isadoc/html/rvi.html RISC-V instruction set]
* [https://osblog.stephenmarz.com/ Small Bare Metal RISCV OS in asm and Rust]
* [https://marz.utk.edu/my-courses/cosc562/riscv/ Page of above with asm code setting up different kernel stack for each hart]
* [https://github.com/cksystemsteaching/selfie Selfie: a minimalist self hosting compiler, riscv64 os, and simulator]
* [https://github.com/cksystemsteaching/selfie/tree/main/theses Selfie page includes 2 well written bare-metal theses]
* [https://github.com/phoenix-rtos Complete open source Microkernel for riscv64 (also arm7, ia32) plus support code]
* [https://github.com/mit-pdos/xv6-riscv XV6: a reimplementation of original Unix for teaching riscv64 OS development]
* [https://github.com/michaelengel/xv6-vf2 Port of XV6 to execute on VisionFive 2 SoC]
* [https://github.com/lupyuen/nuttx-star64 Wonderfully clear and detailed base level port how2: NuttX RTOS to Star64 SoC]
 
[[Category:Bare bones tutorials|RISC-V bare bones]]