# 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 # labeled 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 # 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 < job.log 2>&1 cd / sync shutdown -q EOF } beosSystemVolume() { privateEnsure "$BEOS_CD_FILE" "$(hostTool rawCd)" 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" "$(hostTool rawCd)" 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"* ]] }