interim
interim copied to clipboard
Cannot boot properly into self-built Raspberry image
After executing
./rpi2-build.sh
./rpi2-release.sh
cp release-rpi2/* /media/boot/
umount /media/boot
and inserting the SD card into the Raspberry Pi, it boots into a white screen and is stuck there. No prompt appears. I can't get serial console working either. More instructions on how to debug this would be welcome, like for example how one can try it out in QEMU.
The following however works:
cd docs
tar -xf interim-0.1.0-rpi.tar.gz
cp release-rpi2/* /media/boot/
umount /media/boot
So I'm fairly sure something about the build process is not quite ideal...
I've figured out that the rpi2-build.sh
script expects newlib in a location like on Debian, after patching it the resulting binaries grew a bit. Still a white screen. Debugging by setting the framebuffer color reveals that doing anything involving USPi avoids reaching the remaining code, so that's weird.
I've figured out how to load Interim on a more recent QEMU than in the bundled scripts. Here's my writeup so far:
You'll need a recent QEMU for this with the raspi2 system. The general command line for launching is:
qemu-system-arm -M raspi2 -m 1024 -kernel build/interim-arm.elf -serial stdio
Note that QEMU supports running the raw binary image (located at
build/kernel7.img
), however it expects an entry point of0x10000
instead of0x8000
indevices/rpi2/arm.ld
.The built kernel will hang, to debug why you'll have to boot QEMU with a gdb server:
qemu-system-arm -M raspi2 -m 1024 -kernel build/interim-arm.elf -gdb tcp::26000
Open a suitable
gdb
from the same toolchain as what you've compiled the kernel with:arm-none-eabi-gdb (gdb) target remote localhost:26000 (gdb) symbol-file build/interim-arm.elf (gdb) continue (gdb) ^C (gdb) bt
The backtrace suggests that hardware timers aren't working correctly. The workaround for this is to replace the definition of
uart_init
with the commented out version that uses busy-waiting for delays. Starting the kernel then proceeds up to a white screen and prints out messages successfully via UART until encountering the USPi exception handler. Fixing this requires understanding the USPi library and how it's used...
I eventually got around these issues by upgrading the bundled rpi-boot library and playing with the compilation flags (for some bizarre reason changing the optimization settings allows you to boot further, possibly the fault of undefined behavior and related compiler optimizations removing such code). It appears that structs don't work on ARM at all:
sledge> (struct bar slot 1)
-- clib _write called:
[(struct bar slot 1)]
-- clib _write called:
EXPR: ((struct bar slot 1) . null)
-- clib _write called:
<- compiling 1: (struct bar slot 1)
-- clib _write called:
compiled 1
-- clib _write called:
bar
-- clib _write called:
bar
-- clib _write called:
[insert_symbol] bar entry at 0x11c53a0 (cell: 0x1007d24)
-- clib _write called:
~~ expr 1 res: 0x1007d24
-- clib _write called:
~> bar
nil
-- clib _write called:
sledge> (bar)
-- clib _write called:
[(bar)]
-- clib _write called:
EXPR: ((bar ) . null)
-- clib _write called:
<- compiling 1: (bar )
-- clib _write called:
<error: non-lambda/struct symbol bar in operator position>
-- clib _write called:
compiled 1
-- clib _write called:
[platform_eval] stopped at expression 1: '((bar ) . null)'
nil
sledge>
Structs on ARM are fixed in the meantime btw!
Oh sure, I just haven't tested yet whether booting on the Raspberry Pi works.