This repository aims to provide easy reference code for programming bare metal on the Raspberry Pi 3
This repository aims to provide easy reference code for programming bare metal
in the [Rust systems programming language]. Emphasis is on leveraging Rust's zero-overhead abstractions to compile
on the Raspberry Pi 3 in the [Rust systems programming language]. Emphasis is on
lean code that is readable, concise and safe (at least as safe as it gets on bare-metal hardware).
leveraging Rust's zero-overhead abstractions to compile lean code that is
readable, concise and safe (at least as safe as it gets on bare-metal hardware).
[Rust systems programming language]: https://www.rust-lang.org
[Rust systems programming language]: https://www.rust-lang.org
The target audience is **hobby OS developers** who are new to this hardware. It will give you examples on how to do common
The target audience is **hobby OS developers** who are new to this hardware. It
Operating Systems tasks, like writing to the serial console, reading keystrokes from it or use various peripherals like
will give you examples on how to do common Operating Systems tasks, like writing
a hardware-backed random number generator.
to the serial console, reading keystrokes from it or use various peripherals
like a hardware-backed random number generator.
However, it is *not* a tutorial on how to write a _complete_ OS. I won't cover topics like advanced memory management
However, it is *not* a tutorial on how to write a _complete_ OS. I won't cover
and virtual file systems, or how to implement multi-tasking. Rather, it comprises a set of micro-tutorials that
topics like advanced memory management and virtual file systems, or how to
introduce different topics one after the other. Maybe in the distant future, we might introduce a meta tutorial
implement multi-tasking. Rather, it comprises a set of micro-tutorials that
that combines all the resources to a full-fleged kernel that can multi-task some simple userspace processes, but
introduce different topics one after the other. Maybe in the distant future, we
don't take my word for it.
might introduce a meta tutorial that combines all the resources to a full-fleged
kernel that can multi-task some simple userspace processes, but don't take my
word for it.
## Environment
## Environment
This repo tries to put a focus on user friendliness. Therefore, I made some efforts to eliminate the biggest painpoint in embedded development: _Toolchain hassles_.
This repo tries to put a focus on user friendliness. Therefore, I made some
efforts to eliminate the biggest painpoint in embedded development: _Toolchain
hassles_.
Users eager to try the code should not be bothered with complicated toolchain installation/compilation steps. This is achieved by trying to use the standard Rust toolchain as much as possible, and bridge existing gaps with Docker containers. Please [install Docker for your distro].
Users eager to try the code should not be bothered with complicated toolchain
installation/compilation steps. This is achieved by trying to use the standard
Rust toolchain as much as possible, and bridge existing gaps with Docker
containers. Please [install Docker for your distro].
The setup consists of the following components:
The setup consists of the following components:
1. Compiler, linker and binutils are used from Rust nightly.
1. Compiler, linker and binutils are used from Rust nightly.
2. QEMU will be used for emulation, but RPi3 support in QEMU is very fresh and has not landed in most of the pre-packaged versions of popular distributions. [This] container will provide it ready to go.
2. QEMU will be used for emulation, but RPi3 support in QEMU is very fresh and has not landed in most of the pre-packaged versions of popular distributions. [This] container will provide it ready to go.
Please notice that you won't need to download or prepare the containers upfront. As long as you have docker installed, they will be pulled automatically the first time the Makefile needs them.
Please notice that you won't need to download or prepare the containers
upfront. As long as you have docker installed, they will be pulled automatically
the first time the Makefile needs them.
[install Docker for your distro]: https://www.docker.com/community-edition#/download
[install Docker for your distro]: https://www.docker.com/community-edition#/download
like an USB stick, no special card reader interface required (although many laptops have those these days).
(many manufacturers ship SD cards with such an adapter), so that you can connect
the card to any desktop computer just like an USB stick, no special card reader
interface required (although many laptops have those these days).
You can create an MBR partitioning scheme on the SD card with an LBA FAT32 (type 0x0C) partition, format it
You can create an MBR partitioning scheme on the SD card with an LBA FAT32 (type
and copy `bootcode.bin`, `start.elf` and `fixup.dat` onto it. **Delete all other files or booting might not work**. Or alternatively you can download a raspbian image,
0x0C) partition, format it and copy `bootcode.bin`, `start.elf` and `fixup.dat`
`dd` it to the SD card, mount it and delete the unnecessary .img files. Whichever you prefer. What's important, you'll
onto it. **Delete all other files or booting might not work**. Or alternatively
create `kernel8.img` with these tutorials which must be copied to the root directory on the SD card, and no other `.img`
you can download a raspbian image, `dd` it to the SD card, mount it and delete
files should exists there.
the unnecessary .img files. Whichever you prefer. What's important, you'll
create `kernel8.img` with these tutorials which must be copied to the root
directory on the SD card, and no other `.img` files should exists there.
I'd also recommend to get an [USB serial debug cable](https://www.adafruit.com/product/954). You connect it to the
I'd also recommend to get an [USB serial debug
GPIO pins 14/15.
cable](https://www.adafruit.com/product/954). You connect it to the GPIO pins
14/15.
![UART wiring diagram](doc/wiring.png)
![UART wiring diagram](doc/wiring.png)
@ -72,14 +91,6 @@ sudo screen /dev/ttyUSB0 115200
Exit screen again by pressing <kbd>ctrl-a</kbd><kbd>ctrl-d</kbd>
Exit screen again by pressing <kbd>ctrl-a</kbd><kbd>ctrl-d</kbd>
## Emulation
QEMU currently only emulates UART0, so only the tutorials 05 and above will work, as UART1 is *not* redirected by default.
For that, you would have to add something like `-chardev socket,host=localhost,port=1111,id=aux -serial chardev:aux` (thanks
[@godmar](https://github.com/godmar) for the info).
**!!!WARNING!!!** Qemu emulation is rudimentary, only the most common peripherals are emulated! **!!!WARNING!!!**
## About this repository
## About this repository
The tutorial is basically a combination of two awesome resources.
The tutorial is basically a combination of two awesome resources.
@ -94,39 +105,50 @@ The tutorial is basically a combination of two awesome resources.
## About the hardware
## About the hardware
There are lots of pages on the internet describing the Raspberry Pi 3 hardware in detail, so I'll be brief and
There are lots of pages on the internet describing the Raspberry Pi 3 hardware
cover only the basics.
in detail, so I'll be brief and cover only the basics.
The board is shipped with a [BCM2837 SoC](https://github.com/raspberrypi/documentation/tree/master/hardware/raspberrypi/bcm2837) chip.