boot2

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

commit 1b11e9dca9efcdb09fd2917b96b240e43c8ec91d
parent a84e4ca4303eb3dcad5cf34ca83c2f119019ef1e
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 22 Apr 2026 11:17:23 -0700

Vendor AArch64 catm hex2 source

Diffstat:
Mbootstrap.sh | 13++++++-------
Mpopulate-upstream.sh | 14+++++++++-----
Asrc/catm_AArch64.hex2 | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 148 insertions(+), 12 deletions(-)

diff --git a/bootstrap.sh b/bootstrap.sh @@ -17,7 +17,7 @@ # 0) hex0-seed + hex0_<A>.hex0 -> hex0 # 1) hex0 + hex1_<A>.hex0 -> hex1 # 2) hex1 + hex2_<A>.hex1 -> hex2-0 -# 2b) (hex1|hex2-0) + catm_<A>.(hex1|hex2) -> catm (arch-specific) +# 2b) hex2-0 + catm_<A>.hex2 -> catm # 3a) catm : ELF header + M0_<A>.hex2 -> M0.hex2 # 3b) hex2-0 : M0.hex2 -> M0 # @@ -29,12 +29,11 @@ set -eu ARCH=$1 OUT=$2 -# Map lispcc's lowercase ARCH to stage0-posix's dir name and the two files -# whose extensions differ across arches (catm's source + assembler). +# Map lispcc's lowercase ARCH to stage0-posix's dir name. case "$ARCH" in - aarch64) A=AArch64 ; CATM_SRC=catm_AArch64.hex1 ; CATM_ASM=hex1 ;; - amd64) A=AMD64 ; CATM_SRC=catm_AMD64.hex2 ; CATM_ASM=hex2-0 ;; - riscv64) A=riscv64 ; CATM_SRC=catm_riscv64.hex2 ; CATM_ASM=hex2-0 ;; + aarch64) A=AArch64 ;; + amd64) A=AMD64 ;; + riscv64) A=riscv64 ;; *) echo "bootstrap.sh: unsupported arch '$ARCH'" >&2 ; exit 1 ;; esac @@ -65,6 +64,6 @@ fi "$OUT"/hex0 "$S"/"$A"/hex1_"$A".hex0 "$OUT"/hex1 "$OUT"/hex1 "$S"/"$A"/hex2_"$A".hex1 "$OUT"/hex2-0 -"$OUT"/"$CATM_ASM" "$S"/"$A"/"$CATM_SRC" "$OUT"/catm +"$OUT"/hex2-0 "$S"/"$A"/catm_"$A".hex2 "$OUT"/catm "$OUT"/catm "$OUT"/M0.hex2 "$S"/"$A"/ELF-"$ARCH".hex2 "$S"/"$A"/M0_"$A".hex2 "$OUT"/hex2-0 "$OUT"/M0.hex2 "$OUT"/M0 diff --git a/populate-upstream.sh b/populate-upstream.sh @@ -9,7 +9,7 @@ # $A/hex0_$A.hex0 # $A/hex1_$A.hex0 # $A/hex2_$A.hex1 -# $A/catm_$A.(hex1|hex2) extension differs across arches +# $A/catm_$A.hex2 vendored in src/ for AArch64, mirrored from upstream elsewhere # $A/M0_$A.hex2 # $A/ELF-<arch>.hex2 used by both bootstrap.sh (M0.hex2 link) and # the Makefile's final program link @@ -29,9 +29,9 @@ fi for A in AArch64 AMD64 riscv64; do case "$A" in - AArch64) arch=aarch64 ; CATM=catm_AArch64.hex1 ;; - AMD64) arch=amd64 ; CATM=catm_AMD64.hex2 ;; - riscv64) arch=riscv64 ; CATM=catm_riscv64.hex2 ;; + AArch64) arch=aarch64 ;; + AMD64) arch=amd64 ;; + riscv64) arch=riscv64 ;; esac mkdir -p "$OUT/bootstrap-seeds/POSIX/$A" "$OUT/$A" @@ -40,7 +40,11 @@ for A in AArch64 AMD64 riscv64; do cp "$S/$A/hex0_$A.hex0" "$OUT/$A/" cp "$S/$A/hex1_$A.hex0" "$OUT/$A/" cp "$S/$A/hex2_$A.hex1" "$OUT/$A/" - cp "$S/$A/$CATM" "$OUT/$A/" + if [ "$A" = AArch64 ]; then + cp src/catm_AArch64.hex2 "$OUT/$A/" + else + cp "$S/$A/catm_$A.hex2" "$OUT/$A/" + fi cp "$S/$A/M0_$A.hex2" "$OUT/$A/" cp "$S/$A/ELF-$arch.hex2" "$OUT/$A/" done diff --git a/src/catm_AArch64.hex2 b/src/catm_AArch64.hex2 @@ -0,0 +1,133 @@ +## Copyright (C) 2019 Jeremiah Orians +## Copyright (C) 2020 Sanne Wouda +## This file is part of stage0. +## +## stage0 is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## stage0 is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with stage0. If not, see <http://www.gnu.org/licenses/>. + + + # Register usage: + # X15 => OUTPUT + # X14 => Buffer + # X13 => INPUT + + +## ELF Header + +:ELF_base + +7F 45 4C 46 # e_ident[EI_MAG0-3] ELF's magic number + +02 # e_ident[EI_CLASS] Indicating 64 bit +01 # e_ident[EI_DATA] Indicating little endianness +01 # e_ident[EI_VERSION] Indicating original elf + +03 # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict +00 # e_ident[EI_ABIVERSION] See above + +00 00 00 00 00 00 00 # e_ident[EI_PAD] +02 00 # e_type Indicating Executable +B7 00 # e_machine Indicating AArch64 +01 00 00 00 # e_version Indicating original elf + +&ELF_text 00 00 00 00 # e_entry Address of the entry point +%ELF_program_headers>ELF_base 00 00 00 00 # e_phoff Address of program header table +00 00 00 00 00 00 00 00 # e_shoff Address of section header table + +00 00 00 00 # e_flags +40 00 # e_ehsize Indicating our 64 Byte header + +38 00 # e_phentsize size of a program header table +01 00 # e_phnum number of entries in program table + +00 00 # e_shentsize size of a section header table +00 00 # e_shnum number of entries in section table + +00 00 # e_shstrndx index of the section names + +:ELF_program_headers +:ELF_program_header__text +01 00 00 00 # ph_type: PT-LOAD = 1 +07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7 +00 00 00 00 00 00 00 00 # ph_offset +&ELF_base 00 00 00 00 # ph_vaddr +&ELF_base 00 00 00 00 # ph_physaddr +%ELF_end>ELF_base 00 00 00 00 # ph_filesz +%ELF_end>ELF_base 00 00 00 00 # ph_memsz +01 00 00 00 00 00 00 00 # ph_align + +:ELF_text + +# Where the ELF Header is going to hit +# Simply jump to _start +# Our main function +:_start + e10f41f8 ; LDR_X1_[SP,16]_WB # Get the actual output name + 600c8092 ; SET_X0_TO_FCNTL_H_AT_FDCWD # AT_FDCWD, relative to current working directory + 224880d2 ; SET_X2_TO_577 # Prepare file as O_WRONLY|O_CREAT|O_TRUNC + 033080d2 ; SET_X3_TO_384 # Prepare file as RW for owner only (600 in octal) + 080780d2 ; SET_X8_TO_SYS_OPENAT # The syscall number for openat(), aarch64 has no open() + 010000d4 ; SYSCALL # Now open that file + ef0300aa ; SET_X15_FROM_X0 # Preserve the file pointer we were given + + c81a80d2 ; SET_X8_TO_SYS_BRK # the Syscall # for SYS_BRK + 000080d2 ; SET_X0_TO_0 # Get current brk + 010000d4 ; SYSCALL # Let the kernel do the work + ee0300aa ; SET_X14_FROM_X0 # Set our malloc pointer + + c81a80d2 ; SET_X8_TO_SYS_BRK # the Syscall # for SYS_BRK + e0030eaa ; SET_X0_FROM_X14 # Using current pointer + 00004491 ; ADD_X0_X0_0x100000 # Allocate 1MB + 010000d4 ; SYSCALL # Let the kernel do the work + + e4030091 ; SET_X4_FROM_SP +:core + 818c40f8 ; LDR_X1_[X4,8]_WB # Get the actual input name + 3f0000f1 ; CMP_X1_TO_0 # Check for null string + 41000054 ; SKIP_INST_NE # Hit null be done + ^~done 14 ; ^~done FBRANCH + + 600c8092 ; SET_X0_TO_FCNTL_H_AT_FDCWD # AT_FDCWD, relative to current working directory + 020080d2 ; SET_X2_TO_0 # prepare read_only + 030080d2 ; SET_X3_TO_0 # prevent any interactions + 080780d2 ; SET_X8_TO_SYS_OPENAT # The syscall number for openat(), aarch64 has no open() + 010000d4 ; SYSCALL # Open file! + ed0300aa ; SET_X13_FROM_X0 # Protect INPUT +:keep + 0202a0d2 ; SET_X2_TO_0x100000 # set the size of chars we want + e1030eaa ; SET_X1_FROM_X14 # Where to put it + e0030daa ; SET_X0_FROM_X13 # Where are we reading from + e80780d2 ; SET_X8_TO_SYS_READ # the syscall number for read + 010000d4 ; SYSCALL # call the Kernel + + e20300aa ; SET_X2_FROM_X0 # Number of bytes to write + e1030eaa ; SET_X1_FROM_X14 # What we are writing + e0030faa ; SET_X0_FROM_X15 # Write to target file + 080880d2 ; SET_X8_TO_SYS_WRITE # the syscall number for write + 010000d4 ; SYSCALL # call the Kernel + + 1f0044f1 ; CMP_X0_TO_0x100000 # Check if buffer was fully used + 41000054 ; SKIP_INST_NE # Keep looping if was full + ^~keep 17 ; ^~keep RBRANCH + ^~core 17 ; ^~core RBRANCH # Otherwise move to next file + +:done + # program completed Successfully + 000080d2 ; SET_X0_TO_0 # All is well + a80b80d2 ; SET_X8_TO_SYS_EXIT # put the exit syscall number in x8 + 010000d4 ; SYSCALL # Call it a good day + +:ELF_data +:ELF_end +:ELF_sym +:ELF_str