Minimal freestanding arm64 binary that depthcharge boots as a kernel: parses depthcharge's /firmware/coreboot DTB node, walks the coreboot table, finds LB_TAG_FRAMEBUFFER, and paints red/yellow/green/blue checkpoints (~2s each) into the live boot-splash framebuffer. Verified against coreboot tables header, Linux arm64 booting.rst, and depthcharge's fit.c/boot64.c. Host parser tests pass against the live /sys/firmware/fdt; full red->yellow->green->blue sequence verified end-to-end under qemu-system-aarch64; packed image verifies with the ChromeOS devkeys.
52 lines
1.6 KiB
ArmAsm
52 lines
1.6 KiB
ArmAsm
/*
|
|
* krane-fb-stub — minimal arm64 "hello framebuffer" payload for depthcharge.
|
|
*
|
|
* Entry contract (Linux arm64 boot protocol, verified against
|
|
* linux/Documentation/arch/arm64/booting.rst and depthcharge
|
|
* src/arch/arm/boot64.c + boot64_asm.S):
|
|
* - depthcharge copies the (uncompressed) kernel image to a random
|
|
* 2 MiB-aligned slot in RAM, then jumps to its first byte with
|
|
* x0 = phys addr of flattened DTB, x1..x3 = 0, MMU off.
|
|
* - => everything must be position-independent (PC-relative only).
|
|
*
|
|
* 64-byte arm64 Image header (booting.rst):
|
|
* 0x00 code0 b past header (this is where we are entered)
|
|
* 0x04 code1 unused
|
|
* 0x08 text_offset 0 (image sits AT the 2M-aligned base)
|
|
* 0x10 image_size patched by build.sh to the final file size
|
|
* 0x18 flags bit3 = "place anywhere in 48-bit range"
|
|
* 0x20..0x37 reserved = 0
|
|
* 0x38 magic 0x644d5241 "ARM\x64" (checked by depthcharge)
|
|
* 0x3c res5 0
|
|
*/
|
|
|
|
.section .head, "ax"
|
|
.globl _start
|
|
_start:
|
|
b real_start /* code0: branch to 0x40 */
|
|
.word 0 /* code1 */
|
|
.quad 0 /* text_offset */
|
|
.quad 0 /* image_size — PATCHED by build.sh */
|
|
.quad 1 /* flags: bit3 set (KASLR placement) */
|
|
.quad 0 /* res2 */
|
|
.quad 0 /* res3 */
|
|
.quad 0 /* res4 */
|
|
.word 0x644d5241 /* magic "ARM\x64" */
|
|
.word 0 /* res5 */
|
|
|
|
.section .text, "ax"
|
|
real_start:
|
|
/* depthcharge's SP is dead; use our own stack inside the image */
|
|
adrp x4, stack_top
|
|
add x4, x4, :lo12:stack_top
|
|
mov sp, x4
|
|
bl cmain
|
|
1: b 1b /* cmain never returns; belt+braces halt */
|
|
|
|
.section .stacksec, "aw"
|
|
.align 4
|
|
.globl stack_top
|
|
stack_bottom:
|
|
.zero 16384
|
|
stack_top:
|