boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

crt_arch.h (1531B)


      1 /* tcc-build aarch64 crt_arch.h replacement.
      2  *
      3  * Three things stock musl does that we can't:
      4  *
      5  *   1. `adrp x1, _DYNAMIC` + `add x1, x1, #:lo12:_DYNAMIC` to pass
      6  *      _DYNAMIC's address. arm64-asm.c phase 1+2 has neither the
      7  *      `adrp` mnemonic nor the `:lo12:` ELF reloc syntax, and boot4
      8  *      only links static binaries (no _DYNAMIC) anyway. _start_c
      9  *      ignores its second argument; just don't pass it.
     10  *
     11  *   2. `and sp, x0, #-16` to align the stack. Phase 2's `bic` rejects
     12  *      the bitmask-immediate form ("invert form requires a register").
     13  *      Linux/AAPCS already guarantees a 16-byte-aligned sp at process
     14  *      entry, so the realignment is defensive only.
     15  *
     16  *   3. `mov x29, #0` / `mov x30, #0` / `mov x1, #0` — phase 1 emits
     17  *      these as the 32-bit MOVZ form (sf=0), leaving the upper 32
     18  *      bits of the X register at their entry value. Subsequent code
     19  *      treats x29 as a frame-pointer chain anchor; non-zero high bits
     20  *      crash on the first `stp x29, x30, [...]`. The Linux kernel
     21  *      zeroes all GPRs except sp at process entry (see
     22  *      `start_thread` in arch/arm64/kernel/process.c), so omitting
     23  *      the explicit zeroing is safe — when phase 3 lands, restore
     24  *      the zeroing for defense-in-depth.
     25  *
     26  * What's left is the minimum kernel-to-userland glue: pass sp to
     27  * _start_c so it can read argc/argv/envp/auxv, then jump.
     28  */
     29 __asm__(
     30 ".text \n"
     31 ".global " START "\n"
     32 ".type " START ",%function\n"
     33 START ":\n"
     34 "	mov x0, sp\n"
     35 "	b " START "_c\n"
     36 );