138 lines
5.8 KiB
Bash
138 lines
5.8 KiB
Bash
# shellcheck shell=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"* ]]
|
|
}
|