How Amix Boots¶
Amix boots in two distinct worlds glued together at the very front of the disk. At power-on the "Superkickstart 1.4" bootstrap ROM decides whether to bring up AmigaOS or Amix; if it goes the Amix way it runs an AmigaDOS-style bootblock that contains a 68k bootstrap, which in turn loads and decompresses a checksummed Unix kernel into RAM and hands control to it β . The kernel and everything else live in a normal Unix partition layout that is wrapped in the Amiga Rigid Disk Block (RDB) scheme, including a small 2 MB boot partition whose only job is to hold the kernel image where the bootstrap can find it β .
This page traces that path end to end β ROM, bootblock, kernel decompression, the on-disk RDB layout, how the kernel is built and written to the boot partition, and what our own analysis of amix_21_boot.adf actually shows. For the byte-level dissection of the boot floppy see the boot.adf anatomy page; for partition/filesystem detail see filesystems and disks; for how a fresh kernel gets built and installed see kernel build and install.
The short version¶
- Power-on β Superkickstart 1.4 ROM. Default action boots Amix from the SCSI hard disk (or a boot floppy in DF0). Hold the right mouse button at power-on to load the AmigaOS Kickstart instead β .
- Bootblock β 68k bootstrap. The first sectors of the boot device are a valid AmigaDOS OFS bootblock (
DOS\0+ checksum + 68k code) so the ROM is willing to boot them β . - Bootstrap loads + decompresses the kernel. It reads the compressed kernel image, verifies its checksum, decompresses it into RAM, and jumps in. Failure paths print messages like
Kernel file checksum mismatch.β . - Kernel comes up using the 68030 MMU / HAT layer, mounts root, and runs
init.
On a real install, steps 2β4 read from the 2 MB boot partition on the SCSI disk; during installation they read from the boot floppy instead, which carries a special NFS/RPC-capable install kernel (see The install kernel).
Superkickstart and the dual-boot decision¶
Amix machines ship a special bootstrap ROM Commodore called "Superkickstart 1.4" β . It is what decides, at the very first instant of power-on, whether the machine becomes an AmigaOS box or a Unix workstation:
- Default (no button): boot Amix β from SCSI HD if present, otherwise from a boot floppy in DF0 β .
- Right mouse button held at power-on: load the normal AmigaOS Kickstart and boot AmigaOS β .
This is the canonical Amix "quirk" people remember: one machine, one button, two operating systems. It is documented as a hardware/firmware feature of the A3000UX and A2500UX, not something Amix's own software does. See also the quirks checklist and glossary entry for Superkickstart.
Note: The dual-boot choice is made before any disk is read, so it applies equally whether you intend to boot an installed system off the hard disk or a boot floppy.
The bootblock and the 68k bootstrap¶
Once Superkickstart commits to Amix, it boots the boot device exactly the way AmigaOS firmware boots any floppy or RDB-bootable partition: it reads the bootblock, validates the DOS signature and checksum, and executes the 68k code that follows β
.
What makes the Amix bootblock unusual is that there is no AmigaDOS filesystem behind it. The bootblock's 68k code is a self-contained secondary bootstrap; everything after it on the medium is raw bootstrap code plus the (compressed) kernel payload, not files in an AmigaDOS directory tree β . This is why ordinary AmigaDOS tooling can read the bootblock but not "list" the disk β see our evidence below.
The bootstrap's responsibilities:
- Identify and read the boot volume (string
Load boot volume %dβ ). - Locate the compressed kernel image (string
unix.β ). - Verify the kernel's checksum, decompress it into RAM, and transfer control.
Kernel decompression and checksum verification¶
The on-medium kernel is compressed and checksummed; the bootstrap decompresses it at boot time rather than loading a flat executable β
. We have since reverse-engineered the exact format: the kernel is a standard Unix compress (.Z, LZW -b16) stream at offset 0x2800 that decompresses to a 1,171,200-byte m68k ELF β
, and the checksum is a 16-bit folded sum whose mismatch is non-fatal (the bootstrap warns and boots anyway) β
. Full method, evidence, and the rebuild recipe: Reverse-Engineering the Boot Floppy. The diagnostic strings embedded in amix_21_boot.adf map the steps one-to-one:
| Embedded string β | Meaning |
|---|---|
Load boot volume %d |
Bootstrap is selecting/reading the boot volume |
Decompression failed! |
The compress/LZW kernel could not be unpacked (fatal) |
WARNING! Kernel decompression overrun. |
Decompressed image exceeded its expected size |
WARNING! Kernel file checksum mismatch. |
16-bit folded checksum differs β non-fatal; boots anyway |
Kernel may have been corrupted. |
Follow-up to a checksum/decompression failure |
hat_vtokp_prot: user addr in kernel space |
An SVR4 HAT/MMU panic message (kernel is now running) |
A raw binwalk scan finds no clean ELF header β only noise / false-positive hits β not because the format is opaque, but because binwalk doesn't flag a .Z stream; decode it in one step with tools/extract-kernel.sh β
. The hat_vtokp_prot HAT panic string (readable once decompressed) confirms the payload is a real SVR4 kernel using the 68030 MMU / HAT layer.
On-disk layout: the RDB and the partition table¶
An installed Amix disk uses the Amiga Rigid Disk Block (RDB) partitioning scheme β the same on-disk metadata format AmigaOS uses to describe a SCSI/IDE drive's geometry and partitions β . Amix slots its Unix partitions into RDB partition entries so the Superkickstart ROM can find and boot them.
The installer's default partition layout is four partitions β :
| Partition | Purpose | Notes |
|---|---|---|
/ (root) |
Root filesystem | s5 or UFS; installer defaults to s5 (prompt [s5], empty input β s5) β
, UFS recommended π‘ but must be typed |
| swap | Paging/swap | Larger when the disk is bigger than BREAKPT=120 MB β
|
| boot | Holds the bootable kernel image | 2 MB, fixed by BOOTSIZE (see below) β
|
| data | Remaining user space | Keep partitions β²1 GB π‘ |
Warning: The tape must be at SCSI ID 4 β hard-coded as the literal /dev/rmt/4h in the install scripts β
. The disk is ID 6 by convention: the installer prompts for the disk target and templates the boot partition from it (BPART=/dev/dsk/c${SCSI}d0s${BOOTPART}), so any target works, but the chosen ID is then baked into the device names in /etc/vfstab π‘. Also keep total Fast RAM β€ 16 MB: the kernel hard-codes that ceiling and >16 MB mis-maps the SCSI drive β
. All covered in hardware and the quirks checklist.
The RDB partition type IDs Amix stamps on each partition (via /etc/rdb -F) are now read directly from the installer script β
: boot 0x554e4900 (UNI\0), UNIX root 0x554e4901 (UNI\1), swap 0x72657376 (resv). The installer's own comment notes the Kickstart 2.04 boot-priority algorithm requires the bootable UNIX partition to be type 0x554e4900. Full decode on the root floppy anatomy page.
The 2 MB boot partition and BOOTLEN¶
The boot partition is intentionally tiny and exists only to hold the kernel image where the bootstrap can reach it. Its size is fixed by the installer at 2 MB, and the block count is derived from that β :
# From the root.adf install scripts (β
):
BOOTSIZE=2 # boot partition size in MB
BOOTLEN=$((BOOTSIZE * 2048)) # length in 512-byte blocks => 4096 blocks
So BOOTLEN = BOOTSIZE * 2048 = 4096 blocks of 512 bytes = 2 MB β
. This is the partition that make bootpart writes the kernel into (next section). It is separate from the AmigaOS-readable bootblock concept on the floppy β on the hard disk, the RDB marks this partition bootable and the ROM bootstrap reads the kernel out of it.
From kernel source to a bootable partition¶
Amix is a monolithic SVR4 kernel with no loadable modules β drivers are statically linked in β so installing a new kernel (or a kernel with an added driver) means relinking /unix and rewriting the boot partition β
. The flow, from the Ditto driver paper and the modern driver repos:
# 1. Build the kernel in the kernel source tree.
cd /usr/sys
make # produces the kernel image
# 2. Stage it, then write it to the 2 MB boot partition.
cp relocunix /stand
cd /stand
make bootpart KERNEL=relocunix
# 3. Reboot into the new kernel.
shutdown -i6
rdbunix vs relocunix (a historical rename) π‘¶
The name of the kernel image changed over the life of the project:
- The 1990 Ditto paper calls the built kernel image
rdbunixβ (as cited in the paper). - Amix 2.1 systems and the modern driver repos call it
relocunixβ , and themake bootpartinvocation ismake bootpart KERNEL=relocunixβ .
Treat this as a historical rename and verify per version β rdbunix for the 1990-era toolchain, relocunix for 2.1 π‘. The hydra driver builds natively and relinks the kernel with make force (elf2brel converts the kernel to boot format in the process); see kernel build and install and the hydra case study.
Note: Always keep the old working /unix (or boot partition image) as a fallback before writing a freshly built kernel β a broken boot partition means a machine that won't come up β
.
The two boot2 lineages and the D245/RELA trap¶
The 2 MB boot partition's secondary loader (boot2, an 8192-byte blob at slice offset +0x600
inside the boot1|IBLK|boot2|IBLK|unix chain) exists in two incompatible lineages, and only
one of them can boot modern rebuilt kernels β
:
- The name-based boot2 (sha256
5ab360b1β¦; embedded strings.uvblock .kvsysseg .kvsegmap .kvsegu,"Text and data not contiguous!") resolves kernel sections by segment name. It is what the Amix 2.1 SVR4 installer lays down on every from-scratch install, and it cannot relocate standard flags-based ET_REL kernels (sections classified bySHF_EXECINSTR/WRITE/ALLOC) β it firesAlert('RELA'|AT_DeadEnd)= the D245 4C41 guru before the kernel ever runs β . - The flags-based boot2 (sha256
f287ff3aβ¦; string"No .text, .rodata, or .data!"), built from the sysroot sources, relocates flags-classified kernels cleanly β .
The D245/RELA gurus seen on hard-disk-deployed rebuilt kernels were caused by the foreign on-disk loader, not by the kernel's relocation records: a single-variable splice β replacing ONLY the 8192-byte boot2 (plus its recomputed IBLK checksum) in a byte-identical copy of a D245-failing disk β made the same kernel relocate and execute, reproduced in under 30 s on the bench and then validated 5/5 on the real A4000+Z3660 β .
Scope nuance: the hard-disk bootpart frames the raw ET_REL kernel (makeiblk; no
elf2brel) β the brel/e_type 0xff00 conversion is the boot-floppy path only. A raw
cross-linked ET_REL does not inherently D245 on the hard-disk path; under a name-based boot2 it
always does β
. Because core-2.1.pkg ships the name-based loader inside the stock file set,
any freshly installed system inherits this trap β the modern build pipeline laminates the
flags-based boot2 into /stand/boot2.boot and gates the whole chain with bootchain-verify.py
(see kernel build and install) β
.
Reframing the boot partition on a live system (upgrading the kernel) β ¶
The machine boots the kernel out of the raw UNI\0 boot slice, never /stand/unix β the /stand files are only the framing sources. So swapping in a new kernel means two steps: land the new /stand/unix (and, if it changed, /stand/boot2.boot), then reframe the boot slice β a pkgadd of a kernel package alone changes nothing bootable. The full live cycle was proven end-to-end (upgrade β reframe β cold-boot the new kernel) β
, and the operational details are not obvious:
/stand/CONFIGis absent on an installed box, so stockmake bootpartcannot run β drive the pipeline directly with the slice device supplied explicitly:makeiblkmust be invoked as./makeiblk(it is not onPATH), and the stock/stand/makeiblkis byte-for-byte conformant with the boot-chain contract β no re-implementation needed. The bootpart consumes an ELF ET_REL kernel uncompressed (ib_fullsize=0);elf2brel/compression is the floppy path only.- The flags-based
boot2.boothas a fixedsum -rfingerprint of14193β verify it before writing, because the name-based loader D245s (previous section). - After the
dd,syncand read the slice back to confirm the write landed.
Telling which kernel is actually running (there is no uname field for it): the SVR4 banner reads 2.1c for a cdfs-carrying kernel vs 2.1 for one without, and mount -F cdfs returns errno 22 (the GETFSIND lookup fails) when cdfs is not in the kernel β reliable in that direction β
.
The positive half of that probe is stale. β It used to be "
errno 5means cdfs is present", and that worked only becausecdfswas laundering four different failures into one errno. That was root-caused and fixed, so on a current cdfs kernel the value depends on the media state instead β one live probe of a no-media mount returnederrno 25π‘ (single observation). Read the negative (22= absent), or ask directly withsysfs(GETFSIND, "cdfs"), which is unambiguous both ways. Full account on filesystems and disks.
First boot: the whole stock setup dialog hangs on one exec bit β ¶
The stock first-boot node-name/timezone dialog is gated by a single mode bit. /etc/inittab runs /etc/sysinit at sysinit, which runs /usr/amiga/bin/system.setup iff that file is executable; system.setup ends by chmod -x-ing itself β that exec bit is the stock once-only mechanism. So an unattended/automated install disarms the interactive dialog simply by chmod -x /usr/amiga/bin/system.setup (mode only β the package content, and therefore the package database, is untouched) and drops its own additive /etc/rc2.d/S?? hook to bake identity. Proven across two cold boots: no dialog, identity applied exactly once β
.
Booting Amix with root on an A4091 (and the rootdev dispatch trap)¶
Getting Amix to mount root on a Commodore A4091 (53C710) SCSI controller β a Zorro III board Amix shipped with no driver for β turned out to hinge not on the driver but on how the kernel turns the compiled-in root device number into a SCSI card. This section documents that dispatch path and the panic it produced. All findings here were reproduced locally in Amiberry on the real Amix 2.1c distribution unless tagged otherwise.
Where the root device comes from: /stand/CONFIG β rootdev¶
The root device is compiled into the kernel, not discovered at boot. It is declared in amiga/config/unix.c and fed from the system configuration (/stand/CONFIG) via -DROOTDEV β
:
A concrete config variant (amiga/config/c6s1unix.c) spells out the device numbers it builds β
:
#define C6D0S1 makedevice(18, 22)
dev_t rootdev = C6D0S1; /* root on card 0, target 6, slice 1 */
struct bootobj swapfile = { "", "/dev/dsk/c6d0s2", ... }; /* swap */
So rootdev = c6d0s1 = makedevice(18, 22) (block major 18, minor 22), and swap is c6d0s2. The cN in a device name is computed, not stored: cN = sdcard * 8 + sdunit β so c6d0s1 decodes to card 0, target 6, slice 1. The minor-number fields are decoded in amiga/alien/sd.h β
:
#define SDCARDS 2
#define sdunit(dev) ((dev)>>0 & 07) /* SCSI target id 0-7 */
#define sdcard(dev) ((dev)>>3 & 01) /* card index (queue[] slot) */
#define sdpart(dev) ((dev)>>4 & 07) /* slice/partition */
The sdcard field is the index into the SCSI driver's per-card queue table (only 0 or 1; SDCARDS = 2). Which physical board ends up at card 0 vs card 1 is decided at first root open β and that is exactly where the A4091 boot trap lived. For the full /dev major/minor scheme see the device list reference.
π΄ The mountroot panic was a dispatch bug, not a driver bug¶
π΄ What we believed, and why it was wrong: booting an A4091-only machine panicked at vfs_mountroot with s5mountroot VOP_OPEN error 5. We assumed an early-boot driver / sptalloc-timing problem β that the new 53C710 driver couldn't read the disk that early in boot. Wrong. The A4091 driver reads perfectly post-boot (rc=0), and the panic produced zero driver diagnostics β meaning the driver was never called at all. β
π΄ What it actually is β the phantom A3000. autocon() (amiga/kernel/support.c) hardcoded a phantom A3000 internal SCSI at 0xDD0000 whenever RAM > 7 MB, regardless of whether that hardware exists β
:
sd.c init()/insert() sorts cards ascending by board base address. The phantom's 0xDD0000 sorts before the A4091's 0x40000000, so:
queue[0]= card 0 = phantom A3000 (no hardware) βa3091queuequeue[1]= card 1 = A4091 βa4091queue
The compiled-in rootdev = c6d0s1 decodes to sdcard = 0, so the kernel sent the root read to the non-existent A3000 (a3091queue, no hardware) β EIO β panic β never reaching a4091queue (which is why there were zero A4091 driver lines on the panic). β
This is documented in the Zorro III autoconfig page, which covers autocon() and the phantom-A3000 special case.
β
The fix. The phantom is replaced by a chipset-gated WD33C93 probe that makes the A4091 card 0 when no real A3000 SCSI is present. With the A4091 at card 0, the compiled-in rootdev = c6d0s1, swap = c6d0s2, and /etc/vfstab all resolve to the A4091, and Amix boots fully from the A4091 β root read/write, swap active, multi-user. β
See the detection logic on the Zorro III autoconfig page.
How the kernel picks the root filesystem β by probe, not by configuration¶
The Amiga port ships rootfstype as the empty string β
β where AT&T's generic SVR4 configuration names s5, Amix names nothing and lets the kernel try them all. vfs_mountroot therefore walks the vfssw[] table in order, asking each filesystem in turn to mount the root device, and takes the first that succeeds β
. s5mountroot declines politely with EINVAL when the device is not an s5 filesystem, so the walk continues rather than stopping β
; ufs sits at vfssw[2] in every kernel examined here, install kernels included β
.
Three consequences worth carrying:
- You cannot tell a disk's filesystem from the kernel's configuration, because the kernel does not know it either. A UFS-rooted disk and an s5-rooted disk boot the same kernel unchanged.
s5mountrootappearing in a boot message says nothing about the disk. It is simply the probe that ran first β see the panic below.- A genuine device failure looks like "no filesystem matched", because every probe fails for the same reason and the walk runs off the end of the table.
The mountroot fstype probe sequence¶
The panic surfaces through that same probe walk. The full console sequence is β :
s5mountroot VOP_OPEN error 5
WARNING: nfs_mountroot called
PANIC: vfs_mountroot: cannot mount root: errno 89
The first message comes from the s5 probe, the second from the nfs fallback, and errno 89 (ENOSYS/no more fstypes) is the final give-up. The important point for diagnosis: the EIO is a genuine device read failure (VOP_OPEN error 5 = EIO), surfaced by whichever fstype happens to probe first β not a filesystem-format mismatch. The real root filesystem is ufs, confirmed by /etc/vfstab β
. Seeing s5mountroot in the message does not mean the disk is s5; it means s5 was simply the first probe to hit the dead device.
The install kernel on boot.adf¶
During installation the kernel does not come from the hard disk's boot partition β it comes from the boot floppy (amix_21_boot.adf) in DF0. That floppy carries a special NFS/RPC-capable install kernel β
: alongside the decompression/checksum strings, the bootstrap region contains a full RPC/NFS client string table, consistent with an installer that can pull the distribution over the network as well as from tape. The normal end-to-end install sequence (boot floppy β UFS miniroot on root.adf β tape at SCSI ID 4 β make bootpart β reboot) is described in filesystems and disks and the install walkthrough.
What the real boot.adf actually contains¶
Everything below is reproduced from our own read-only analysis of amix_21_boot.adf using tools/inspect-adf.sh β
. (The ADF itself is proprietary Commodore material; obtain it from amigaunix.com or archive.org β do not commit it.)
Run the inspector against your own copy:
What it reports, and what each finding means:
- It is a valid AmigaDOS OFS bootblock. The first bytes are
44 4f 53 00=DOS\0, followed by the bootblock checksum and 68k bootstrap code β so the Superkickstart ROM is willing to boot it β . - There is no AmigaDOS filesystem.
xdftool listfails withInvalid Root Block @880, because the disk is bootblock + raw bootstrap + payload, not an AmigaDOS directory tree β . - The kernel is a Unix
compress(.Z, LZW) stream at0x2800that decompresses to a 1,171,200-byte m68k ELF; its 16-bit checksum is non-fatal (warns, boots anyway). Decode it withtools/extract-kernel.shβ . - It is an NFS/RPC install kernel. A full NFS/RPC client string table and the
hat_vtokp_prot: user addr in kernel spaceHAT/MMU panic string are present (readable once decompressed) β . binwalkshows only noise β not because the format is opaque but because it doesn't flag.Z; the stream decodes cleanly to ELF β .
For the full byte offsets, the equivalent root/patch-disk findings, and how to read the inspector output, see the boot.adf anatomy page.
See also¶
- Anatomy of the boot ADF β byte-level dissection of
amix_21_boot.adf. - Filesystems and disks β RDB, s5 vs UFS, swap, and the full partition story.
- Kernel architecture β the monolithic SVR4 kernel, HAT/MMU layer, switch tables.
- Kernel build and install β
makeβrelocunixβmake bootpartin detail. - Hardware and requirements β Superkickstart ROM, SCSI ID 6/ID 4, the 16 MB ceiling.
- Quirks checklist β the dual-boot button and other surprises in one place.
- Emulation Fidelity β the 68030 bus-error-frame semantics the demand-paging boot leans on, and the SCSI INT2 bootstrap-latency gotcha.
- Install walkthrough β running the whole flow under emulation.
- The A4091 (53C710) SCSI driver β the driver behind the root-on-A4091 boot.
- Zorro III autoconfig and
autocon()β the phantom-A3000 special case and the chipset-gated A4091 detection. - Device list reference β the SCSI
/devmajor/minor scheme behindcN d0 sN.
Sources¶
- amix-kerntools brief
boot2-d245-trap(2026-07-16): single-variable boot2 splice, loader forensics (sha5ab360b1β¦vsf287ff3aβ¦), bench + 5/5 metal validation 2026-07-15. - Research brief Β§3 (Boot process & disk layout) and Β§10 (boot.adf anatomy),
sources/research-brief.md. amix_21_boot.adfanalysis viatools/inspect-adf.sh:DOS\0OFS bootblock, failedxdftool list(Invalid Root Block @880), kernel decompression/checksum strings, NFS/RPC string table,hat_vtokp_protHAT panic string, no clean ELF.amix_21_root.adfinstall scripts (viatools/inspect-adf.sh):BOOTSIZE=2,BOOTLEN=BOOTSIZE*2048,BREAKPT=120,BPART=/dev/dsk/c${SCSI}d0s${BOOTPART}. The root-filesystem prompt is[s5]and empty input selects s5;ANS="ufs"appears only as a case branch reached when the user typesufs(corrected 2026-07-19 β previously recorded here as the default).- Michael Ditto, Writing Amix Device Drivers, 1990 European Amiga Developer's Conference (the
rdbunixkernel image name; statically linked monolithic kernel;makein/usr/sys). - Modern driver repos for the
relocunix/make bootpart KERNEL=relocunixflow: https://github.com/asokero/va2000-amix, https://github.com/isoriano1968/hydra-amix. - amigaunix.com (Superkickstart dual-boot via right mouse button, hardware requirements): https://www.amigaunix.com/.
- The A4091-on-Amix project β
NOTES.mdΒ§16, Β§18, Β§19 (root-on-A4091 / mountroot dispatch trap, reproduced locally β ) andsrc//tools/. amiga/config/unix.c(rootdev = ROOTDEV,-DROOTDEV) andamiga/config/c6s1unix.c(C6D0S1 = makedevice(18,22), swapc6d0s2);amiga/alien/sd.h(SDCARDS,sdunit/sdcard/sdpartmacros).src/kernel-patches/support.cβ theautocon()phantom-A3000 fix replaced by the chipset-gated WD33C93 probe;src/kernel-patches/sd.cβ the0x02020054,&a4091queueregistry row;src/a4091-wr.cβ the 53C710 READ+WRITE driver.- a4091.device open-source project: https://github.com/A4091/a4091-software (A4091 autoboot ROM + SCRIPTS assembler).
- The 2026-08-12/14 RAM campaign proof reports (workspace record) β
β root-filesystem selection is by probe, not by configuration: the Amiga port ships
rootfstypeempty (AT&T generic sayss5),vfs_mountrootwalksvfssw[],s5mountrootreturnsEINVALpolitely so the walk continues, andufssits atvfssw[2]in every kernel including the install kernels. Same source for thecdfserrno de-laundering that makes the olderrno 5probe stale; the π‘ no-mediaerrno 25value is a single live probe from the 2026-08-14/15 golden-regeneration event, carried unchanged. Cross-checked against thevfs_mountrootdisassembly recorded on building a kernel. - The Installer-NG Waves 5β6 field campaign (amix-installng @
7106f1b, amix-packagemanager @4539ad2), 2026-07-22/24 β a blank-diskβbootable-install effort that root-caused these platform behaviours on the Amiberry bench and the real A4000+Z3660 (acceptance-run captures, s5/UFS state reads, and the on-metal digest attestation) β (π‘ where tagged).