You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
8.5 KiB
Markdown

5 years ago
# Bare-metal and Operating System development tutorials in Rust on the Raspberry Pi 3
7 years ago
[![Build Status](https://travis-ci.org/rust-embedded/rust-raspi3-OS-tutorials.svg?branch=master)](https://travis-ci.org/rust-embedded/rust-raspi3-OS-tutorials)
6 years ago
5 years ago
## Notice
5 years ago
**The tutorials are being rewritten [on the v2 branch](https://github.com/rust-embedded/rust-raspi3-OS-tutorials/tree/rewrite_for_v2), so please have a look from time to time. The master branch will only receive updates if something breaks.**
5 years ago
_Cheers,
Andre_
## Introduction
6 years ago
This repository aims to provide easy reference code for programming bare metal
on the Raspberry Pi 3 in the [Rust systems programming language]. Emphasis is on
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).
6 years ago
6 years ago
[Rust systems programming language]: https://www.rust-lang.org
5 years ago
The target audience is **hobby OS developers** who are new to [ARM's 64 bit ARMv8-A
architecture](https://developer.arm.com/products/architecture/cpu-architecture/a-profile/docs).
It will give you examples on how to do common Operating Systems tasks, like writing
to the serial console, setting up virtual memory and exception handling and using
various peripherals like a hardware-backed random number generator.
However, it is *not* a tutorial on how to write a _complete_ OS from start to finish.
Rather, it comprises a set of micro-tutorials that introduce different topics one
after the other. Maybe in the distant future, a meta tutorial that
combines all the resources to a full-fleged kernel that can multi-task some simple
userspace processes is possible, but don't take my word for it.
6 years ago
6 years ago
## 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_.
6 years ago
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].
6 years ago
The setup consists of the following components:
1. Compiler, linker and binutils are used from Rust nightly.
6 years ago
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.
6 years ago
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.
6 years ago
If you want to know more about docker and peek at the the containers used in these
tutorials, please refer [to the repository's docker folder](docker).
6 years ago
[install Docker for your distro]: https://www.docker.com/community-edition#/download
[This]: https://github.com/andre-richter/docker-raspi3-qemu
## Prerequisites
7 years ago
6 years ago
Before you can start, you'll need a suitable Rust toolchain.
6 years ago
```bash
curl https://sh.rustup.rs -sSf | sh -s -- \
--default-toolchain nightly \
--component rust-src llvm-tools-preview clippy rustfmt
cargo install cargo-xbuild cargo-binutils
6 years ago
```
Additionally, a Micro SD card with [firmware
files](https://github.com/raspberrypi/firmware/tree/master/boot) on a FAT
filesystem is needed.
7 years ago
I recommend to get a [Micro SD card USB
adapter](http://media.kingston.com/images/products/prodReader-FCR-MRG2-img.jpg)
(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).
7 years ago
You can create an MBR partitioning scheme on the SD card with an LBA FAT32 (type
0x0C) partition, format it and copy `bootcode.bin`, `start.elf` and `fixup.dat`
onto it. **Delete all other files or booting might not work**. Alternatively,
you can download a raspbian image, `dd` it to the SD card, mount it and delete
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.
7 years ago
I'd also recommend to get an [USB serial debug
cable](https://www.adafruit.com/product/954). You connect it to the GPIO pins
14/15.
7 years ago
6 years ago
![UART wiring diagram](doc/wiring.png)
6 years ago
Then, run `screen` on your desktop computer like
7 years ago
6 years ago
```bash
sudo screen /dev/ttyUSB0 115200
7 years ago
```
6 years ago
Exit screen again by pressing <kbd>ctrl-a</kbd> <kbd>ctrl-d</kbd>
7 years ago
## About this repository
The tutorial is basically a combination of two awesome resources.
1. First of all, it is a fork of [Zoltan Baldaszti]'s awesome [tutorial] on bare metal programming on RPi3 in `C`.
1. Rust code will be based on his files, READMEs will be adapted, and I might change things here and there if I think it is beneficial. However, credits to this guy plz!
2. The second props go to [Jorge Aparicio] for ["The Embedonomicon"], from which the boot code is taken.
[Zoltan Baldaszti]: https://github.com/bztsrc
[tutorial]: https://github.com/bztsrc/raspi3-tutorial
[Jorge Aparicio]: https://github.com/japaric
["The Embedonomicon"]: https://rust-embedded.github.io/embedonomicon/
## About the hardware
7 years ago
There are lots of pages on the internet describing the Raspberry Pi 3 hardware
in detail, so I'll be brief and cover only the basics.
7 years ago
The board is shipped with a [BCM2837
SoC](https://github.com/raspberrypi/documentation/tree/master/hardware/raspberrypi/bcm2837)
chip. That includes a
7 years ago
- VideoCore GPU
6 years ago
- ARM-Cortex-A53 CPU (ARMv8)
7 years ago
- Some MMIO mapped pheripherals.
Interestingly the CPU is not the main processor on the board. When it's powered
up, first GPU runs. When it's finished with the initialization by executing the
code in bootcode.bin, it will load and execute the start.elf executable. That's
not an ARM executable, but compiled for the GPU. What interests us is that
start.elf looks for different ARM executables, all starting with `kernel` and
ending in `.img`. As we're going to program the CPU in AArch64 mode, we'll need
`kernel8.img` only, which is the last to look for. Once it's loaded, the GPU
triggers the reset line on the ARM processor, which starts executing code at
address 0x80000 (or more precisely at 0, but the GPU puts an ARM jump code there
first).
The RAM (1G for the Raspberry Pi 3) is shared among the CPU and the GPU, meaning
one can read what the other has written into memory. To avoid confusion, a well
defined, so called [mailbox
interface](https://github.com/raspberrypi/firmware/wiki/Mailboxes) is
established. The CPU writes a message into the mailbox, and tells the GPU to
read it. The GPU (knowing that the message is entirely in memory) interprets it,
and places a response message at the same address. The CPU has to poll the
memory to know when the GPU is finished, and then it can read the response.
Similarily, all peripherals communicates in memory with the CPU. Each has it's
dedicated memory address starting from 0x3F000000, but it's not in real RAM
(called Memory Mapped IO). Now there's no mailbox for peripherals, instead each
device has it's own protocol. What's common for these devices that their memory
must be read and written in 32 bit units at 4 bytes aligned addresses (so called
words), and each has control/status and data words. Unfortunately Broadcom (the
manufacturer of the SoC chip) is legendary bad at documenting their
products. The best we've got is the BCM2835 documentation, which is close
enough.
There's also a Memory Management Unit in the CPU which allows creating virtual
address spaces. This can be programmed by specific CPU registers, and care must
be taken when you map these MMIO addresses into a virtual address space.
7 years ago
Some of the more interesting MMIO addresses are:
```
0x3F003000 - System Timer
0x3F00B000 - Interrupt controller
0x3F00B880 - VideoCore mailbox
0x3F100000 - Power management
0x3F104000 - Random Number Generator
0x3F200000 - General Purpose IO controller
0x3F201000 - UART0 (serial port, PL011)
0x3F215000 - UART1 (serial port, AUX mini UART)
0x3F300000 - External Mass Media Controller (SD card reader)
0x3F980000 - Universal Serial Bus controller
```
For more information, see Raspberry Pi firmware wiki and documentation on github.
6 years ago
7 years ago
https://github.com/raspberrypi
Good luck and enjoy hacking with your Raspberry! :-)
6 years ago
6 years ago
Andre
## License
Licensed under the MIT license ([LICENSE-MIT](LICENSE) or http://opensource.org/licenses/MIT).