Skip to content

Commit

Permalink
Merge pull request #81 from fayalalebrun/dtb
Browse files Browse the repository at this point in the history
Pi Zero Compatibility; DTB parser
  • Loading branch information
fayalalebrun authored Apr 26, 2021
2 parents 3c28d0a + 1b5e367 commit cb0c7d0
Show file tree
Hide file tree
Showing 32 changed files with 2,099 additions and 203 deletions.
33 changes: 18 additions & 15 deletions .dir-locals.el
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
((nil . ((eval . (let ((root (projectile-project-root)))
(let ((command (concat "arm-none-eabi-gdb -i=mi -ex \"target remote localhost:1234\" -ex \"symbol-file " root "src/kernel/build/kernel.sym\"")))
(setq-local gud-gud-gdb-command-name command)
(setq-local gud-gdb-command-name command)
(set (make-local-variable 'compile-command)
(concat "cd " (concat root "src") " && make test"))
(use-local-map (copy-keymap (current-local-map)))
(local-set-key [f5] 'compile)
(local-set-key [f6] 'co/gdb)
(let ((command (concat "arm-none-eabi-gdb -i=mi -ex \"target remote localhost:1234\" -ex \"symbol-file " root "src/kernel/build/kernel.sym\"")))
(setq-local gud-gud-gdb-command-name command)
(setq-local gud-gdb-command-name command)
(set (make-local-variable 'compile-command)
(concat "cd " (concat root "src") " && make test"))
(let ((map (make-sparse-keymap)))

(set-keymap-parent map (current-local-map))
(use-local-map map)
(local-set-key [f5] 'compile)
(local-set-key [f6] 'co/gdb)

(defun co/gdb ()
(interactive)
(async-shell-command (concat "cd "
(concat (projectile-project-root) "src")
" && "
"make debug") nil 0)
(gdb gud-gdb-command-name))))))))
(defun co/gdb ()
(interactive)
(async-shell-command (concat "cd "
(concat (projectile-project-root) "src")
" && "
"make debug") nil 0)
(gdb gud-gdb-command-name)))))))))
2 changes: 2 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"version": "0.2.0",
"configurations": [
{

"name": "(gdb) Attach - C/C++",
"type": "cppdbg",
"request": "launch",
Expand All @@ -20,6 +21,7 @@
},
"miDebuggerServerAddress": "localhost:1234",
"preLaunchTask": "run_debug"

},
{
"name": "(gdb) Attach - Native",
Expand Down
1 change: 1 addition & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"label": "stop_debug",
"detail": "Stops the qemu emulator at port 1234",
"type": "shell",

"command": "kill $(sudo lsof -t -i:1234)"
}
]
Expand Down
34 changes: 19 additions & 15 deletions src/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ LDFLAGS += -nostartfiles -fcommon -nolibc
# PI_CFLAGS = -mfpu=vfp -march=armv6zk -mtune=arm1176jzf-s -nostartfiles

# variables to define in the preprocessor.
# amount of memory the PMM should try to allocate, may or may not match the actual amount of
# memory in the system. Stuff will crash if this number is more than the actual amount of
# memory. TODO: autodetect this at boot
MEMORY = 1G
LOG_LEVEL ?= 4

# Available options:
Expand All @@ -33,7 +29,18 @@ SOURCEDIR = src
BUILDDIR = build
# every directory named `include` will have its contents autoincluded
INCLUDEDIR = include


BOARD = raspi2

ifeq ($(BOARD),raspi2)
CPU = cortex-a7
DTB = $(CURDIR)/dtb/bcm2709-rpi-2-b.dtb
else ifeq ($(BOARD),raspi0)
CPU = arm1176
DTB = $(CURDIR)/dtb/bcm2708-rpi-zero-dumped.dtb
endif


# Seeds the random order in which tests are run.
TESTS_SEED = $(shell date '+%s')
Expand Down Expand Up @@ -95,37 +102,34 @@ configure: configure_qemu configure_toolchain


build: $(BUILDDIR)/kernel.elf configure | builddir
build_pi: $(BUILDDIR)/kernelPi.img | builddir
build_pi: $(BUILDDIR)/kernel.img | builddir

test: build configure | builddir
#${QEMU} -M versatilepb -cpu arm1176 -sd $(BUILDDIR)/card.sd -m $(MEMORY) -nographic -semihosting -kernel build/flash.bin -append "-load 0x410000 0x14000"
${QEMU} -kernel $(BUILDDIR)/kernel.elf -m $(MEMORY) -serial stdio -monitor none -M raspi2 -cpu $(CPU) -nographic -append "-load 0x410000 0x14000" -semihosting
${QEMU} -kernel $(BUILDDIR)/kernel.elf -serial stdio -monitor none -M $(BOARD) -cpu $(CPU) -nographic -append "-load 0x410000 0x14000" -semihosting

run: build configure | builddir
# nographic to turn off the gui
# monitor none to disable stdio monitoring so
# serial stdio works
#${QEMU} -M versatilepb -cpu arm1176 -sd $(BUILDDIR)/card.sd -m $(MEMORY) -nographic -semihosting -monitor none -serial stdio -kernel build/flash.bin -append "-load 0x410000 0x14000"
${QEMU} -kernel $(BUILDDIR)/kernel.elf -m $(MEMORY) -serial stdio -monitor none -M raspi2 -cpu $(CPU) -nographic -append "-load 0x410000 0x14000" -semihosting
${QEMU} -kernel $(BUILDDIR)/kernel.elf -serial stdio -monitor none -M $(BOARD) -cpu $(CPU) -nographic -append "-load 0x410000 0x14000" -semihosting

debug: build configure | builddir
${QEMU} -kernel $(BUILDDIR)/kernel.elf -m $(MEMORY) -serial stdio -monitor none -M raspi2 -cpu $(CPU) -nographic -append "-load 0x410000 0x14000" -semihosting -S -s
${QEMU} -kernel $(BUILDDIR)/kernel.elf -serial stdio -monitor none -M $(BOARD) -cpu $(CPU) -nographic -semihosting -S -s

start_debug: build configure | builddir
$(GDB) -ex "target remote localhost:1234" -ex "symbol-file $(BUILDDIR)/kernel.sym"

$(BUILDDIR)/kernel.elf: $(OBJECT_FILES) | builddir
$(LD) -T linker/kernel.ld $(LDFLAGS) -Wl,-Map,kernel.map $^ -o $@
$(OBJCOPY) -I binary -O elf32-littlearm $(DTB) $(BUILDDIR)/dtb.o
$(LD) -T linker/kernel.ld $(LDFLAGS) -Wl,-Map,kernel.map $^ $(BUILDDIR)/dtb.o -o $@
$(OBJCOPY) --only-keep-debug $(BUILDDIR)/kernel.elf $(BUILDDIR)/kernel.sym
$(OBJCOPY) --strip-debug $(BUILDDIR)/kernel.elf

# Begin Pi Make
# (aka, building for a real pi. TODO: This is mostly untested)
$(BUILDDIR)/kernelPi.elf: $(C_OBJECT_FILES) | builddir
$(CC) -T kernelPi.ld -O2 $(PI_CFLAGS) $^ -o $@

$(BUILDDIR)/kernelPi.img: $(BUILDDIR)/kernelPi.elf | builddir
$(OBJCOPY) $< -O binary $@
$(BUILDDIR)/kernel.img: $(BUILDDIR)/kernel.elf | builddir
$(OBJCOPY) $< -O binary $@(Z
# End Pi Make

builddir:
Expand Down
4 changes: 2 additions & 2 deletions src/kernel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ The [makefile](Makefile) in this directory contains a number of configuration op
| Configuration opion | description |
| --- | --- |
| CFLAGS | Flags given to the c compiler |
| MEMORY | The amount of memory given to qemu. Until memory detection works, must be `1G` |
| DEFINITIONS | These are variables given to the c preprocessor. Options for these are listed below. |
| KERNEL_PARAMS | Currently not supported and outdated |
| SOURCEDIR | The name of the directory containing the sourcecode. |
| BUILDDIR | The name of the directory containing object files and binaries |
| INCLUDEDIR | Any directory in SOURCEDIR with this name, will be globally included in every c file. This means they can be included with `#include <something.h>` instead of `#include "something.h"`. |
| BOARD | The board which will be emulated by QEMU. Can be `raspi0` or `raspi2`. |
| TEST_MAIN_FILE | The name of the file generated to contain all [tests](src/test/README.md). |
| TESTS_SEED | The seed used to randomize the order in which the tests are run. |
| CPU | The cpu type emulated by qemu. Supported cpu types are the `arm1176` and `cortex-a7`|



## Definitions
Expand Down
21 changes: 21 additions & 0 deletions src/kernel/dtb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Device Tree Files for QEMU

In this directory, there are a number of DTB files we use when running the kernel in QEMU.

## What is a DTB file?
In an ARM board, most peripherals are use via memory-mapped IO, which means there is no standard way to poll what kind of peripherals are present in the system and where in memory to find them. Additionally, there is no way to find out how much memory is present in the system. A Device Tree is the standardized way in which the bootloader communicates to the kernel how the system looks like, including the type of cpu, the amount of memory available, what peripherals can be found and any other details we need to for our kernel to interact with the current board correctly.

A **DTS** file is the human-readable representation of a device tree, while a **DTB** is a binary version, more suitable for parsing, and usually what you feed into the OS.

## How does the kernel obtain the DTB file?
One of the responsibilities of a board's bootloader is to load the board's DTB file and pass it to the kernel. Thus on kernel startup, we can expect a pointer to the DTB to be in the `r2` register.

In QEMU however, there is no provision made for a DTB to be passed to our program. Thus we must work around it, and build the DTB into the kernel, and use this built-in DTB instead.

## Why use a dumped DTB file?
Certain bootloaders make changes to the board's standard DTB file before passing it to the kernel. For example, the Raspberry Pi Zero's default DTB does not have the memory property filled in. Thus, if we weren't using a dumped DTB, we would not be getting the correct memory value.

## Further Reading
https://devicetree-specification.readthedocs.io/en/v0.3/
https://devicetree-specification.readthedocs.io/en/v0.3/flattened-format.html
https://elinux.org/Device_Tree_Usage
Binary file added src/kernel/dtb/bcm2708-rpi-zero-dumped.dtb
Binary file not shown.
Loading

0 comments on commit cb0c7d0

Please sign in to comment.