joeylib2/installer/lib/beos.sh
2026-10-13 14:01:46 -05:00

137 lines
5.8 KiB
Bash

# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
# See LICENSE.md for license information.
# SPDX-License-Identifier: MIT
#
# BeOS R5 from your own BeOS 5 Professional CD (a private file, never
# downloaded: ./install.sh import the CloneCD .img, or the .7z holding it),
# shared by the components that make something of it: beosR5 (the headers
# and libraries make beos builds against) and beosVm (the machine its
# programs run in). Source from a component.
#
# The CD is three Mode 1 data tracks: the ISO 9660 one that boots a BeOS
# floppy image (El Torito), the x86 BeOS system as a BFS volume ("BeOS 5 Pro
# Edition"), and the PowerPC one. The x86 track is read with Haiku's
# bfs_shell (component haikuTools), run in a user namespace of its own
# (unshare -r): it makes each file it copies out with the file's BeOS mode
# before writing it, and a read-only one could not be written otherwise.
#
# The VM (beosVmPrepare) boots the CD's floppy image, which boots the first
# BFS system volume it finds: a copy of the x86 track, on the machine's
# first disk, with the job runner as its UserBootscript. The runner is the
# Haiku VMs' (installer/lib/haiku.sh), so the gates drive both alike: a disk
# labelled HAIKU_JOB_VOLUME holding job.sh (Tracker mounts it), job.sh run
# there with its output in job.log, then the machine powered off (the
# kernel's apm and enable_shutdown settings), so QEMU exits. R5 has no
# serial port to say so on: its serial driver finds the ports through the
# ISA plug and play bus, which is taken out (below). Changes to the system:
# - the ISA plug and play bus (busses/config_manager/isa) is removed: in
# the fail-safe (VESA) video mode it crashes into the kernel debugger
# the first time a driver asks the configuration manager for a device.
# QEMU's PC has no ISA plug and play cards for it to find.
# - the swap file and unsupported graphics card alerts are switched off.
#
# beosBfs IMAGE run the bfs_shell commands on stdin against IMAGE
# beosJobRunner the job runner (the VM's UserBootscript)
# beosSystemVolume OUT the x86 track as a BFS volume image
# beosVmPin what the VM is rebuilt for: the CD and the steps
# beosVmPrepare DIR the VM's disks: DIR/system.img and DIR/floppy.img
# beosVmVerify DIR the job runner is on DIR's system disk
# shellcheck source=installer/lib/haiku.sh
source "$JOEY_INSTALLER/lib/haiku.sh"
BEOS_CD_FILE="toolchains/firmware/beos/beos5pro.img"
# The x86 track's first sector and length, from the CD's table of contents
# (the image is pinned by its checksum, so they cannot move).
BEOS_SYSTEM_TRACK_FIRST=35109
BEOS_SYSTEM_TRACK_SECTORS=148780
BEOS_RAW_CD_TOOL="tools/rawCd.py"
# The VM's disks, in the component's folder.
BEOS_VM_SYSTEM_DISK="system.img"
BEOS_VM_FLOPPY="floppy.img"
# Seconds the runner waits for Tracker to mount the job disk.
BEOS_JOB_WAIT_SECONDS=30
# The kernel's settings: power off at shutdown.
BEOS_KERNEL_SETTINGS="apm true
enable_shutdown true"
BEOS_ISA_BUS="beos/system/add-ons/kernel/busses/config_manager/isa"
BEOS_NAG_SETTINGS="stop_swap_nagging stop_vga_nagging"
beosBfs() {
unshare -r true 2> /dev/null ||
die "reading the BeOS volume needs user namespaces (unshare -r), which this system does not allow"
{ cat; printf 'quit\n'; } | unshare -r "$JOEY_OPT/haikuTools/bin/bfs_shell" "$1"
}
# beosJobRunner -- the UserBootscript the VM runs at every boot (after R5's
# Bootscript has started the servers, Tracker and Deskbar).
beosJobRunner() {
cat <<EOF
# JoeyLib's job runner (installer/lib/beos.sh): when Tracker mounts a disk
# labelled $HAIKU_JOB_VOLUME holding job.sh, job.sh is run there (its output in
# job.log) and the machine powers off. Without one, an ordinary boot.
tries=0
while [ ! -f /$HAIKU_JOB_VOLUME/job.sh ]; do
tries=\$((tries + 1))
if [ \$tries -gt $BEOS_JOB_WAIT_SECONDS ]; then
exit 0
fi
sleep 1
done
cd /$HAIKU_JOB_VOLUME
/bin/sh ./job.sh > job.log 2>&1
cd /
sync
shutdown -q
EOF
}
beosSystemVolume() {
privateEnsure "$BEOS_CD_FILE"
python3 "$JOEY_REPO/$BEOS_RAW_CD_TOOL" track "$JOEY_REPO/$BEOS_CD_FILE" "$BEOS_SYSTEM_TRACK_FIRST" "$BEOS_SYSTEM_TRACK_SECTORS" "$1" ||
die "could not read the x86 track of $BEOS_CD_FILE"
}
beosVmPin() {
local steps
steps="$({ beosJobRunner; printf '%s\n' "$BEOS_KERNEL_SETTINGS" "$BEOS_ISA_BUS" "$BEOS_NAG_SETTINGS"; declare -f beosSystemVolume beosVmPrepare; } | sha256sum | cut -d' ' -f1)"
printf '%s:%s\n' "$(privateSha1For "$BEOS_CD_FILE")" "$steps"
}
beosVmPrepare() {
local dir="$1"
local part="$1.part"
local nag
rm -rf "$part"
mkdir -p "$part"
beosSystemVolume "$part/$BEOS_VM_SYSTEM_DISK"
python3 "$JOEY_REPO/$BEOS_RAW_CD_TOOL" eltorito "$JOEY_REPO/$BEOS_CD_FILE" "$part/$BEOS_VM_FLOPPY" ||
die "could not read the boot floppy image of $BEOS_CD_FILE"
beosJobRunner > "$part/UserBootscript"
printf '%s\n' "$BEOS_KERNEL_SETTINGS" > "$part/kernel"
: > "$part/empty"
{
printf 'cp :%s /myfs/home/config/boot/UserBootscript\n' "$part/UserBootscript"
printf 'cp :%s /myfs/home/config/settings/kernel/drivers/kernel\n' "$part/kernel"
for nag in $BEOS_NAG_SETTINGS; do
printf 'cp :%s /myfs/home/config/settings/%s\n' "$part/empty" "$nag"
done
printf 'rm /myfs/%s\n' "$BEOS_ISA_BUS"
} | haikuBfs "$part/$BEOS_VM_SYSTEM_DISK" > "$part/bfs.log" || die "cannot prepare the BeOS system disk; bfs_shell's log: $part/bfs.log"
rm -f "$part/UserBootscript" "$part/kernel" "$part/empty" "$part/bfs.log"
rm -rf "$dir"
mv "$part" "$dir"
}
beosVmVerify() {
local runner
[ -s "$1/$BEOS_VM_FLOPPY" ] || return 1
runner="$(haikuBfs "$1/$BEOS_VM_SYSTEM_DISK" <<< "cat /myfs/home/config/boot/UserBootscript" || true)"
[[ "$runner" == *"$HAIKU_JOB_VOLUME"* ]]
}