boot6-gen-runscm.sh (4433B)
1 #!/bin/sh 2 ## boot6-gen-runscm.sh — emit run.scm driving tcc3 to build seed-kernel. 3 ## 4 ## tcc3 -c each translation unit (kernel.S, kernel.c, mem.c) → .o, then 5 ## tcc3 links + emits a flat arm64 boot Image directly (no `ld -T 6 ## kernel.lds`, no objcopy). The link line is three tcc flags: 7 ## 8 ## -nostdlib -static freestanding link, no startfiles 9 ## -Wl,-Ttext=0x40080000 base address (arm64 RAM_BASE + 10 ## text_offset; QEMU's `-kernel` loads 11 ## us here) 12 ## -Wl,--oformat=binary flat-bytes output (objcopy -O binary 13 ## equivalent). Required because QEMU's 14 ## `-kernel <ELF>` path doesn't run the 15 ## arm64 boot wrapper that puts DTB in 16 ## x0 — only the flat-Image path does. 17 ## Detection is by `ARM\x64` magic at 18 ## file offset 0x38, which is in 19 ## kernel.S's Image header at the top of 20 ## `.text`. 21 ## 22 ## Everything else the kernel needs from the linker is supplied by 23 ## conventions tcc3 already honors: 24 ## 25 ## _start hard-coded entry symbol; kernel.S's arm64 Image 26 ## header is named `_start` (not `_head`) so this works 27 ## out of the box. 28 ## __bss_start auto-defined at the start of merged .bss via the 29 ## `bss-start-symbol` simple-patch. 30 ## _end auto-defined by stock tcc at the end of merged .bss 31 ## (tcc_add_linker_symbols). kernel.S uses it to 32 ## bracket the bss-zero loop and to compute the 33 ## Image-header `image_size` field; kernel.c uses it 34 ## to place the kernel heap above the loaded image. 35 ## 36 ## Usage: bootprep/boot6-gen-runscm.sh <arch> 37 ## Writes build/<arch>/src/run/boot6.scm. 38 39 set -eu 40 [ "$#" -eq 1 ] || { echo "usage: $0 <arch>" >&2; exit 2; } 41 ARCH=$1 42 OUT=build/$ARCH/src/run/boot6.scm 43 mkdir -p "$(dirname "$OUT")" 44 45 # Per-arch link parameters. aarch64 alone needs --oformat=binary because 46 # QEMU's `-kernel <ELF>` path skips the arm64 boot wrapper that puts DTB 47 # in x0 — only the flat-Image path honors it (detected via the `ARM\x64` 48 # magic at file offset 0x38 in kernel.S's Image header). amd64/riscv64 49 # stay as ELF: QEMU's `-kernel` path on those arches consumes ELF 50 # directly (PVH note for amd64, OpenSBI for riscv64). 51 case "$ARCH" in 52 aarch64) TTEXT=0x40080000; OUT_FILE=Image; LINK_OFORMAT='"-Wl,--oformat=binary"' ;; 53 amd64) TTEXT=0x40000000; OUT_FILE=kernel.elf; LINK_OFORMAT= ;; 54 riscv64) TTEXT=0x80200000; OUT_FILE=kernel.elf; LINK_OFORMAT= ;; 55 *) echo "boot6-gen: unsupported arch '$ARCH'" >&2; exit 2 ;; 56 esac 57 58 # Kernel CFLAGS — freestanding, static, no host startfiles. We omit gcc's 59 # -mgeneral-regs-only (no tcc equivalent); kernel.S enables CPACR_EL1.FPEN 60 # in stext before the first `bl kmain`, so tcc's SIMD callee-saves in 61 # function prologues don't trap. 62 KCFLAGS='"-nostdlib" "-ffreestanding" "-static"' 63 64 cat > "$OUT" <<EOF 65 ;; boot6 run.scm — build seed-kernel ELF with tcc3. 66 ;; Generated by bootprep/boot6-gen-runscm.sh; reads use in/, writes out/. 67 68 (define (must r tag) 69 (if (and (car r) (= 0 (cdr r))) 70 r 71 (begin 72 (write-string stderr "boot6: step failed: ") 73 (write-string stderr tag) 74 (write-string stderr "\n") 75 (exit 1)))) 76 77 (write-string stdout "boot6: tcc3 -c kernel.S\n") 78 (must (run "in/tcc3" $KCFLAGS "-c" "-o" "out/kernel-asm.o" "in/kernel.S") 79 "kernel.S -> kernel-asm.o") 80 81 (write-string stdout "boot6: tcc3 -c kernel.c\n") 82 (must (run "in/tcc3" $KCFLAGS "-Iin" "-c" "-o" "out/kernel.o" "in/kernel.c") 83 "kernel.c -> kernel.o") 84 85 (write-string stdout "boot6: tcc3 -c mmu.c\n") 86 (must (run "in/tcc3" $KCFLAGS "-Iin" "-c" "-o" "out/mmu.o" "in/mmu.c") 87 "mmu.c -> mmu.o") 88 89 (write-string stdout "boot6: tcc3 -c mem.c\n") 90 (must (run "in/tcc3" $KCFLAGS "-c" "-o" "out/mem.o" "in/mem.c") 91 "mem.c -> mem.o") 92 93 (write-string stdout "boot6: tcc3 link $OUT_FILE\n") 94 (must (run "in/tcc3" "-nostdlib" "-static" 95 "-Wl,-Ttext=$TTEXT" 96 $LINK_OFORMAT 97 "-o" "out/$OUT_FILE" 98 "out/kernel-asm.o" "out/kernel.o" "out/mmu.o" "out/mem.o") 99 "link $OUT_FILE") 100 101 (write-string stdout "boot6: ALL-OK\n") 102 (exit 0) 103 EOF