Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pi Zero Compatibility; DTB parser #81

Merged
merged 23 commits into from
Apr 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0a2ec92
Add dtb files
fayalalebrun Mar 9, 2021
cb8d7bf
Add board option to makefile; Add linking of dtb into binary
fayalalebrun Mar 9, 2021
e2615d5
Add board configuration documentation
fayalalebrun Mar 9, 2021
96d8050
Move dtb files to kernel directory
fayalalebrun Mar 9, 2021
2df8f6a
Add raspberry pi zero dumped device tree
fayalalebrun Mar 13, 2021
4a29658
Fix raspi0 core being disabled
fayalalebrun Mar 13, 2021
ce0916b
Fix timer tests failing
fayalalebrun Mar 14, 2021
43ba07f
Remove old memory detection mechanism; Add use of embedded dtb
fayalalebrun Mar 14, 2021
d94a02e
Add dtb struct; Add check for dtb magic number
fayalalebrun Mar 14, 2021
e695e4e
Add first implementation of dtb parser
fayalalebrun Mar 16, 2021
859b505
Fix bugs in dtb parser, now functional
fayalalebrun Mar 16, 2021
1779627
Add dtb memory detection; Overhaul hardware detection using DTB
fayalalebrun Mar 17, 2021
9695a82
Merge branch 'multiprocessing' into dtb
fayalalebrun Mar 18, 2021
5b2322c
Add first implementation BCM2835 support
fayalalebrun Mar 20, 2021
b88563d
Fix wrong address used for interrupt registers
fayalalebrun Mar 20, 2021
2c6c6cc
Refactor timer test to use chipset functions
fayalalebrun Mar 20, 2021
4f96a82
Fix system timer implementation; Fix failing test on raspi0
fayalalebrun Mar 20, 2021
b1425ce
Remove unused DTB files
fayalalebrun Mar 24, 2021
1aca175
Add dtb readme
fayalalebrun Mar 24, 2021
6af63f6
Remove unnecessary memory variable
fayalalebrun Mar 24, 2021
2830c90
Refactore dtb source to use existing ALIGN macro
fayalalebrun Mar 24, 2021
dbf0db5
Move memory detection responsibility to hardware info
fayalalebrun Mar 24, 2021
1b5e367
Merge remote-tracking branch 'origin/multiprocessing' into dtb
fayalalebrun Apr 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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