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.
Andre Richter 91575eaa2c
Refactor tutorial 06
4 years ago
..
.vscode Switch to rust-analyzer 4 years ago
src Refactor tutorial 06 4 years ago
Cargo.lock Bump to register 0.5.x 4 years ago
Cargo.toml Bump to register 0.5.x 4 years ago
Makefile Refactor tutorial 06 4 years ago
README.md Refactor tutorial 06 4 years ago
kernel Refactor tutorial 06 4 years ago
kernel8.img Refactor tutorial 06 4 years ago

README.md

Tutorial 06 - Drivers: GPIO and UART

tl;dr

Now that we enabled safe globals in the previous tutorial, the infrastructure is laid for adding the first real device drivers. We throw out the magic QEMU console and use a real UART now. Like serious embedded hackers do!

Notable additions

  • For the first time, we will be able to run the code on the real hardware.
    • Therefore, building is now differentiated between the RPi 3 and the RPi4.
    • By default, all Makefile targets will build for the RPi 3.
    • In order to build for the the RPi4, prepend BSP=rpi4 to each target. For example:
      • BSP=rpi4 make
      • BSP=rpi4 make doc
    • Unfortunately, QEMU does not yet support the RPi4, so BSP=rpi4 make qemu won't work.
  • A driver::interface::DeviceDriver trait is added for abstracting BSP driver implementations from kernel code.
  • Drivers are stored in src/bsp/device_driver, and can be reused between BSPs.
    • We introduce the GPIO driver, which pinmuxes the RPi's PL011 UART.
    • Most importantly, the PL011Uart driver: It implements the console::interface::* traits and is from now on used as the main system console output.
  • BSPs now contain a memory map in src/bsp/memory.rs. In the specific case, they contain the Raspberry's MMIO addresses which are used to instantiate the respectivedevice drivers.
  • We also modify the panic! handler, so that it does not anymore rely on println!, which uses the globally-shared instance of the UART that might be locked when an error is encountered (for now this can't happen due to the NullLock, but with a real lock it becomes an issue).
    • Instead, it creates a new UART driver instance, re-initializes the device and uses that one to print. This increases the chances that the system is able to print a final important message before it suspends itself.

Boot it from SD card

Some steps for preparing the SD card differ between RPi3 and RPi4, so be careful.

Common for both

  1. Make a single FAT32 partition named boot.
  2. On the card, generate a file named config.txt with the following contents:
init_uart_clock=48000000

Pi 3

  1. Copy the following files from the Raspberry Pi firmware repo onto the SD card:
  2. Run make and copy the kernel8.img onto the SD card.

Pi 4

  1. Copy the following files from the Raspberry Pi firmware repo onto the SD card:
  2. Run BSP=rpi4 make and copy the kernel8.img onto the SD card.

Note: Should it not work on your RPi4, try renaming start4.elf to start.elf (without the 4) on the SD card.

Common again

  1. Insert the SD card into the RPi and connect the USB serial to your host PC.
  2. Run screen (you might need to install it first):
sudo screen /dev/ttyUSB0 230400
  1. Hit Enter to kick off the kernel boot process. Observe the output:
[0] Booting on: Raspberry Pi 3
[1] Drivers loaded:
      1. BCM GPIO
      2. BCM PL011 UART
[2] Chars written: 93
[3] Echoing input now
  1. Exit screen by pressing ctrl-a ctrl-d or disconnecting the USB serial.

Diff to previous