boot/bios/ now holds the MBR, the El Torito stub and the real-mode stage 2; boot/uefi/ is empty and documented. Separate directories rather than #ifdefs, because the two share almost nothing. A BIOS loader lives in 16-bit real mode, reaches the firmware through software interrupts, and walks itself up into long mode. A UEFI loader is a 64-bit PE that the firmware has already placed in long mode with paging on, calling services through a table of function pointers. What they do share is the hand-off contract, which boot/README.md now writes down: ELF segments placed, long mode, a 24-byte-entry memory map at E820_MAP_ADDR, framebuffer geometry at VBE_INFO_ADDR. That contract is the point of documenting it now. UEFI's GetMemoryMap returns EFI_MEMORY_DESCRIPTORs, and the right move is to translate them into the entries kernel/arch/x86_64/e820.c already parses rather than teach the kernel a second format. Build output paths under $(BUILD)/boot are unchanged; only sources moved.
91 lines
3.7 KiB
Shell
91 lines
3.7 KiB
Shell
#!/bin/sh
|
|
# Build a bootable SchOS ISO.
|
|
#
|
|
# tools/posix/mkiso.sh [output.iso]
|
|
#
|
|
# The disc boots through El Torito's "no emulation" mode, which is the only
|
|
# one of the three that fits how SchOS actually loads itself.
|
|
#
|
|
# floppy emulation caps the image at 2.88 MB; the ramdisk-root kernel
|
|
# alone is bigger than that.
|
|
# hard disk emulation presents the image through the BIOS's INT 13h, and
|
|
# SchOS's loader does not use INT 13h -- it drives
|
|
# the IDE controller's registers directly, which
|
|
# cannot reach a BIOS-emulated drive.
|
|
# no emulation the BIOS loads a chosen run of sectors at 0x7C00
|
|
# and gets out of the way. That is this.
|
|
#
|
|
# So the layout below is deliberate: -boot-load-size is 1 + STAGE2_SECTORS,
|
|
# which makes the BIOS place both boot/cdboot and the whole of stage2 in memory
|
|
# before anything of ours runs. That puts stage2 at 0x7E00 -- byte for byte the
|
|
# arrangement bootasm.S produces on a hard disk. From there the only difference
|
|
# is that stage2main.c reads the kernel back with ATAPI instead of ATA.
|
|
#
|
|
# STAGE2_SECTORS comes from the environment, set by the Makefile, because this
|
|
# same number also lives in boot/bios/bootasm.S, boot/bios/stage2main.c and the dd offsets
|
|
# in schos.img's recipe. It was previously written out by hand in three
|
|
# separate spots in this file alone, and raising it for the boot logo is what
|
|
# turned that from a latent hazard into a broken image.
|
|
#
|
|
# NOT using -boot-info-table on purpose: it patches 56 bytes over offset 8 of
|
|
# the boot image, which is the middle of cdboot's code. stage2main.c finds
|
|
# where it was loaded from by reading the El Torito boot catalog instead.
|
|
|
|
set -e
|
|
|
|
BUILD=${BUILD:-build}
|
|
OUT=${1:-schos.iso}
|
|
STAGE2_SECTORS=${STAGE2_SECTORS:-48}
|
|
STAGE2_BYTES=$((STAGE2_SECTORS * 512))
|
|
LOAD_SIZE=$((1 + STAGE2_SECTORS))
|
|
STAGING="$BUILD/iso"
|
|
|
|
CDBOOT="$BUILD/boot/cdboot"
|
|
STAGE2="$BUILD/boot/stage2"
|
|
KERNEL="$BUILD/kernel/kernel"
|
|
|
|
for f in "$CDBOOT" "$STAGE2" "$KERNEL"; do
|
|
[ -f "$f" ] || { echo "mkiso: missing $f -- run make first" >&2; exit 1; }
|
|
done
|
|
|
|
# The three pieces must be contiguous and at these exact sizes: stage2main.c's
|
|
# readseg() finds the kernel at sector (1 + STAGE2_SECTORS) of the boot image,
|
|
# so a short stage2 would silently shift the kernel out from under it.
|
|
cdboot_sz=$(wc -c < "$CDBOOT")
|
|
stage2_sz=$(wc -c < "$STAGE2")
|
|
[ "$cdboot_sz" -eq 512 ] || { echo "mkiso: cdboot is $cdboot_sz bytes, expected 512" >&2; exit 1; }
|
|
[ "$stage2_sz" -eq "$STAGE2_BYTES" ] || { echo "mkiso: stage2 is $stage2_sz bytes, expected $STAGE2_BYTES (STAGE2_SECTORS=$STAGE2_SECTORS)" >&2; exit 1; }
|
|
|
|
rm -rf "$STAGING"
|
|
mkdir -p "$STAGING/boot"
|
|
|
|
cat "$CDBOOT" "$STAGE2" "$KERNEL" > "$STAGING/boot/schos.bin"
|
|
|
|
# xorriso if it is here, mkisofs otherwise. Both accept the El Torito flags
|
|
# below unchanged -- xorriso's -as mkisofs mode exists precisely to be
|
|
# argument-compatible with it. The fallback is not academic: there is no xorriso
|
|
# package for Windows in scoop, where this is developed, but cdrtools provides
|
|
# mkisofs.exe.
|
|
if command -v xorriso >/dev/null 2>&1; then
|
|
MKISOFS="xorriso -as mkisofs"
|
|
elif command -v mkisofs >/dev/null 2>&1; then
|
|
MKISOFS="mkisofs"
|
|
else
|
|
echo "mkiso: need xorriso or mkisofs on PATH" >&2
|
|
echo " Windows: scoop install cdrtools" >&2
|
|
echo " Debian/Ubuntu: apt install xorriso" >&2
|
|
exit 1
|
|
fi
|
|
|
|
$MKISOFS \
|
|
-quiet \
|
|
-V SCHOS \
|
|
-A "SchOS" \
|
|
-b boot/schos.bin \
|
|
-no-emul-boot \
|
|
-boot-load-size "$LOAD_SIZE" \
|
|
-o "$OUT" \
|
|
"$STAGING"
|
|
|
|
echo "==> $OUT ($(wc -c < "$OUT") bytes)"
|
|
echo " qemu-system-x86_64 -cdrom $OUT -boot d"
|