RISC-V Meaty Skeleton with QEMU virt board: Difference between revisions
[unchecked revision] | [unchecked revision] |
Content deleted Content added
No edit summary |
m Bot: Replace deprecated source tag with syntaxhighlight |
||
(13 intermediate revisions by 5 users not shown) | |||
Line 1:
{{BeginnersWarning}}
{{Rating|1}}
{{Template:Kernel designs}}
This tutorial assumes you have completed [[RISC-V_Bare_Bones|RISC-V Bare Bones]] on the QEMU <code>virt</code> board, or alternatively, [[HiFive-1_Bare_Bones|HiFive-1 Bare Bones]]. If not, you should complete them first for an overview of how to boot your own operating system on RISC-V. This tutorial is deliberately brief on concepts that have already been covered in the bare bones tutorials and their transitive prerequisites.
Line 36 ⟶ 40:
Fetch the latest version of GDB through [https://ftp.gnu.org/gnu/gdb/ https://ftp.gnu.org/gnu/gdb/]. The latest version at the time of writing is 12.1:
<
export GDB_VERSION="12.1"
wget https://ftp.gnu.org/gnu/gdb/gdb-${GDB_VERSION}.tar.xz
</syntaxhighlight>
Unpack the archive:
<
tar xvf gdb-${GDB_VERSION}.tar.xz
</syntaxhighlight>
Now move into the source directory:
<
pushd gdb-${GDB_VERSION}/
</syntaxhighlight>
Create a build directory and move into it:
<
mkdir build
pushd build/
</syntaxhighlight>
Now export a few variables as with building a cross-GCC or cross-binutils:
<
export PREFIX="$HOME/opt/cross"
export TARGET=riscv64-elf
export PATH="$PREFIX/bin:$PATH"
</syntaxhighlight>
Configuration options are mostly the same as with building cross-GCC or cross-binutils. In particular, you may wish to enable the following features:
Line 73 ⟶ 77:
* <code>--with-expat</code>: Build with Expat, a library for XML parsing. Requires development headers for Expat to be installed on the build host
<
../configure --target=$TARGET \
--prefix="$PREFIX" \
Line 83 ⟶ 87:
--enable-tui=yes \
--with-expat
</syntaxhighlight>
Now build the source code (this can take a while):
<
make -j$(nproc)
</syntaxhighlight>
And install:
<
make -C gdb install
</syntaxhighlight>
If you wish to keep the source tree available for conveniently re-building GDB in the future (e.g. with a different set of options), clean up the build files now:
<
make clean
</syntaxhighlight>
Move one level up to the project root:
<
popd
</syntaxhighlight>
Remove the <code>build/</code> directory we created:
<
rm -rf build/
</syntaxhighlight>
Move up one more level:
<
popd
</syntaxhighlight>
Double check our cross-debugger is properly installed:
<
which -- $TARGET-gdb || echo $TARGET-gdb is not in the PATH
</syntaxhighlight>
Now you may safely remove the source tree and archive, if you wish:
<
rm -rf gdb-${GDB_VERSION}/
rm gdb-${GDB_VERSION}.tar.xz
</syntaxhighlight>
If <code>$PREFIX/bin</code> is not in your path already, you may wish to persist it by writing it to your profile:
<
echo "export PATH=\"\$HOME/opt/cross/bin:\$PATH\"" >> $HOME/.profile
source $HOME/.profile
</syntaxhighlight>
==Dependencies==
Line 160 ⟶ 164:
Fetch the source code from the <code>v0.0.1</code> release of [https://github.com/DonaldKellett/marvelos https://github.com/DonaldKellett/marvelos] code-named "Meaty Skeleton", using [https://git-scm.com/ Git]:
<
git clone --branch v0.0.1 https://github.com/DonaldKellett/marvelos.git
</syntaxhighlight>
Operating systems development is about being an expert. Take the time to read the code carefully through and understand it. Please seek further information and help if you don't understand aspects of it. This code is minimal and almost everything is done deliberately, often to pre-emptively solve future problems.
Line 189 ⟶ 193:
Run <code>make $TARGET</code> with <code>TARGET</code> set to your desired target to execute the specified target. For example, to build the kernel image and run it in QEMU:
<
make run
</syntaxhighlight>
Additionally, the default target is <code>all</code> if not specified:
<
make
</syntaxhighlight>
<
# Build
CC=riscv64-elf-gcc
Line 242 ⟶ 246:
rm -vf *.o
rm -vf $(KERNEL_IMAGE)
</syntaxhighlight>
===Kernel source===
Line 248 ⟶ 252:
====src/common/common.h====
<
#ifndef COMMON_H
#define COMMON_H
Line 256 ⟶ 260:
#endif
</syntaxhighlight>
====src/common/common.c====
<
#include <stdarg.h>
#include "common.h"
Line 278 ⟶ 282:
asm volatile ("wfi");
}
</syntaxhighlight>
====src/syscon/syscon.h====
<
#ifndef SYSCON_H
#define SYSCON_H
Line 294 ⟶ 298:
#endif
</syntaxhighlight>
====src/syscon/syscon.c====
<
#include <stdint.h>
#include "syscon.h"
Line 312 ⟶ 316:
*(uint32_t *)SYSCON_ADDR = 0x7777;
}
</syntaxhighlight>
====src/uart/uart.h====
<
#ifndef UART_H
#define UART_H
Line 333 ⟶ 337:
#endif
</syntaxhighlight>
====src/uart/uart.c====
<
#include <stddef.h>
#include <stdint.h>
Line 559 ⟶ 563:
va_end(arg);
}
</syntaxhighlight>
====src/kmain.c====
<
#include "uart/uart.h"
#include "syscon/syscon.h"
Line 579 ⟶ 583:
poweroff();
}
</syntaxhighlight>
==Running the project==
Line 596 ⟶ 600:
Also note that this example RISC-V OS runs in M-mode usually reserved for firmware, rather than the S-mode recommended for RISC-V supervisors (OSes). If you wish to follow the RISC-V conventions closely, you may want to look into RISC-V privilege modes and [https://github.com/riscv-software-src/opensbi OpenSBI] early on and port your OS kernel accordingly. More information about RISC-V privilege modes available on [[RISC-V#Privileges|our wiki]].
==See also==
* [[RISC-V|RISC-V]]
* [[RISC-V_Bare_Bones|RISC-V Bare Bones]]
* [[HiFive-1_Bare_Bones|HiFive-1 Bare Bones]]
* [[Meaty_Skeleton|Meaty Skeleton]]
[[Category:RISC-V]]
[[Category:Bare_bones_tutorials]]
[[Category:C]]
[[Category:QEMU]]
[[Category:Level_1_Tutorials]]
===External links===
* [https://github.com/twilco/riscv-from-scratch RISC-V from scratch]
* [https://github.com/sgmarz/osblog The Adventures of OS]
* [https://linuxfromscratch.org/ Linux From Scratch]
* [https://github.com/riscv-software-src/opensbi OpenSBI]
|