|
3 weeks ago | |
---|---|---|
Dependencies | 1 month ago | |
data/Fonts | 1 month ago | |
src | 3 weeks ago | |
.gitignore | 1 month ago | |
.gitmodules | 1 month ago | |
Build.sh | 1 month ago | |
BuildFontAtlases.sh | 1 month ago | |
BuildOS.sh | 1 month ago | |
COPYING | 1 month ago | |
LICENSE | 1 month ago | |
ReadMe.org | 3 weeks ago | |
RunProfiler.sh | 1 month ago |
ReadMe.org
Raspberry Pi Bare Metal
Setup
-
Download the Arm GNU toolchain: x86_64 Linux hosted cross toolchains,
AArch64 bare-metal target (aarch64-none-elf)
link -
Download the latest firmware (use the Download ZIP button, aka this; a slightly smaller repo is here)
-
Format an SD card as
msdos
partitioned, with aFAT32
at least as large as the firmware/boot contents + yourkernel8.img
-
Copy the contents of the firmware
boot/
onto the SD card -
Remove all
kernel*.img
files
config.txt
Put the following for config.txt
:
hdmi_group=2
# Mode 82 = 1920x1080 60Hz
hdmi_mode=82
Build
-
Run
BuildFontAtlases.sh
(only need to do this once or if fonts change) -
Run
Build.sh
-
Copy
kernel8.img
to the SD card
References
Raspberry Pi:
Arm:
My stumbling blocks
-
Not having all the firmware on the SD card
-
Not writing the LED blink code correctly, i.e. I wasn't waiting while the LED was off, so it was just solid on. Viewing the disassembly helped clue me in to it.
-
Frame buffer pointer needed to be converted from a GPU address to a CPU address
Unaligned memory access is not supported without the MMU enabled
GCC started using NEON/floating point registers to set integer values due to optimizations, but I don't think I had initialized NEON yet.
NEON/SIMD was accessible, and alignment checking was disabled. The actual problem was made clear when I started playing with the alignment of e.g. this sequence:
ldr x1, =__bss_start
ldr d0, [x1, #8] // works
ldr d0, [x1, #4] // exception.
This reddit thread finally cleared it up:
With the MMU off, the ARM core must treat all memory as device memory (which does not support unaligned access) since it doesn't actually know what's MMIO and what's DRAM. You have to provide that information to the core via page tables and MAIR bits if you want unaligned accesses to be allowed.
This is confirmed in ARM DDI 0487J.a
, The AArch64 Application Level Memory Model B2.5 Alignment support that device memory faults on unaligned access.
Using the floating point/SIMD registers before initializing
Hack around it by passing -mgeneral-regs-only
.
00000000000000e8 <initializeFramebuffer>:
e8: a9b37bfd stp x29, x30, [sp, #-208]!
ec: 910003fd mov x29, sp
f0: f9000fe0 str x0, [sp, #24]
f4: 910083e0 add x0, sp, #0x20
f8: 4f000400 movi v0.4s, #0x0
Initializing the stack pointer after exception level change
This was finally pointed out to me while reading ARM DAI 0527A
(Bare-metal Boot Code for ARMv8-A Processors):
5.2.2 Initializing stack pointer registers The stack pointer register is implicitly used in some instructions, for example, push and pop. You must initialize it with a proper value before using it. In an MPCore system, different stack pointers must point to different memory addresses to avoid overwriting the stack area. If SPs in different Exception levels are used, you must initialize all of them.