Course Home: https://cs140e.sergio.bz/
The original course uses these build tools:
nightly-2018-01-09
version of RustXargo
to build and customize Rust'sstd
libraryaarch64-none-elf
GNU toolchain
But newer Rust (e.g. nightly-2023-05-25
) provides -build-std
feature and good support for aarch64-unknown-none
target so Xargo
and aarch64-none-elf
GNU toolchain are no longer needed:
rustup default nightly-2023-05-25
cargo install cargo-binutils # make it easy to use the LLVM tools
This course uses a customized std lib, but it still depends on some built-in libs such as core
, alloc
etc. To build for the aarch64-unknown-none
target, one of the following methods can be choosed:
- Method 1: Install pre-compiled copy of
core
,alloc
etc libraries:rustup target add aarch64-unknown-none # add pre-compiled copy of std library for aarch64-unknown-none
- Method 2: Install
rust-src
to be able to recompilecore
,alloc
etc libraries:rustup component add rust-src
Before talking about build, there are 2 problems about test:
- Where to run test?
- On local machine: This usually means run test on host target like
x86_64-unknown-linux-gnu
. However, this project is designed foraarch64-unknown-none
so some targe specific code will not work. - On real Pi hardware (or QEMU): No previous problem but inconvinient.
- On local machine: This usually means run test on host target like
- This project used a customized std while test depends on the built-in full-featured
std
lib. Two possible solutions:- Make test not depends on built-in
std
using the custom_test_frameworks feature: https://os.phil-opp.com/testing/. But it comes with certain limitations: cannot use#[should_panic]
, multi-thread,print!
(not supported by our customized std) etc. - Make the code switch to use built-in
std
when testing by using#[cfg(test)]
conditional compilation. But it means dependencies likeos/pi
,2-fs/fat32
needs to be adjusted as well.
- Make test not depends on built-in
Currently, run test on local machine + switch std
is chosen:
- For
os/kernel
and its dependencies likeos/pi
,2-fs/fat32
, introduce acustom-std
feature to switch between customized std and built-in std. - Use
#[cfg(not(test))]
for target specific code.
cd os/kernel
# For "Method 1": use pre-compiled
cargo build --release --target aarch64-unknown-none --features custom-std
# For "Method 2": recompile `core`, `alloc` by ourselves
cargo build --release --target aarch64-unknown-none --features custom-std -Z build-std=core,alloc
rust-objcopy target/aarch64-unknown-none/release/kernel -O binary <overwrite kernel8.img at root directory of SD card>
cd os/kernel
cargo test
QEMU can be used to emulate a Raspberry Pi 3B+:
qemu-system-aarch64 -machine raspi3b -serial null -serial stdio -kernel target/aarch64-unknown-none/release/kernel # or the bin file produced by rust-objcopy
PS: The first -serial null
redirects UART0
(PL011
) to the host void device, the second -serial stdio
to redirect UART1
(mini UART
) to the host stdio.
From Raspberry Pi's doc:
The Raspberry Pi uses a configuration file instead of the BIOS you would expect to find on a conventional PC. The system configuration parameters, which would traditionally be edited and stored using a BIOS, are stored instead in an optional text file named config.txt. This is read by the GPU before the ARM CPU and Linux are initialised. It must therefore be located on the first (boot) partition of your SD card, alongside bootcode.bin and start.elf.
A sample config.txt
:
arm_64bit=1
NOTE: For this course, DO NOT set kernel_old=1
which will loads kernel to the memory address 0x0
. Instead, kernel should be loaded to 0x80000
.