interim icon indicating copy to clipboard operation
interim copied to clipboard

Cannot boot properly into self-built Raspberry image

Open wasamasa opened this issue 8 years ago • 5 comments

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...

wasamasa avatar Dec 27 '16 13:12 wasamasa

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.

wasamasa avatar Feb 22 '17 22:02 wasamasa

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 of 0x10000 instead of 0x8000 in devices/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...

wasamasa avatar Mar 10 '17 10:03 wasamasa

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>

wasamasa avatar May 20 '17 13:05 wasamasa

Structs on ARM are fixed in the meantime btw!

mntmn avatar Oct 13 '18 11:10 mntmn

Oh sure, I just haven't tested yet whether booting on the Raspberry Pi works.

wasamasa avatar Oct 15 '18 08:10 wasamasa