Anatomy of the Root (miniroot) Floppy¶
The Amix root floppy (amix_21_root.adf, 901,120 bytes / 880 KB) is a System V s5 "miniroot": a small s5 filesystem packed with the installer — about 30 m68k ELF binaries (cpio, fsck, mkfs, dd, amixpkg, rdb, …), the /bin/sh install scripts that drive partitioning and the tape extraction, a POSIX tar member, and the viper_kludge tape work-around plus its viper.README. ✅ (local analysis of amix_21_root.adf)
Correction (2026-07-05): this floppy's on-disk filesystem is
s5, not UFS. Its superblock sits at byte0x200with the s5 magic0xfd187e20(s_type=2= 1024-byte logical blocks,s_fsize=880= exactly the image size). The UFS magic0x00011954appears in the image only inside the bundledmkfs_ufs/fsck_ufsELF binaries, never at a superblock — which is why the string-basedtools/inspect-adf.shheuristic (it keys offlost+found) mislabels it "UFS miniroot." This is consistent with the installer's ownROOT_FSYS="s5"("Johann ROM can only boot s5 filesystem", below): s5 is the boot-capable root fs. ✅ (forensic superblock analysis, 2026-07-05)
Unlike the boot floppy, the root floppy has no AmigaDOS bootblock — its first sectors are zeroed and the Kickstart ROM never boots it directly. It is mounted by the install kernel after you swap it in. This page dissects its on-disk structure and the install logic it carries. For the end-to-end procedure, see the install walkthrough; to understand how all three install disks are produced, see the build pipeline.
Licensing. The root floppy is Commodore material. Until 2026-09-23 this project treated it as abandonware, not licensed for redistribution; since then the Amix release restriction is lifted (see
AGENTS.md§5). Do not commit it here — this is a text knowledge hub. Obtain it from amigaunix.com or the Internet Archive, then run the read-only tooling below against your own copy.
Identify your copy:
file : amix_21_root.adf
size : 901120 bytes (901120 = standard 880 KB Amiga DD floppy)
sha256: 890da5e52f00cae74b817b42d1b94c3438f57b8c13b3d2b055e8b116a3feac56
tools/inspect-adf.sh on amix_21_root.adf; cross-check against sources/CHECKSUMS.txt)
No bootblock — and the body is s5, not UFS¶
The root floppy does not start with the AmigaDOS DOS\0 signature that a boot disk has. The boot area is zeroed, so any AmigaDOS-FS tool refuses it: ✅
$ tools/inspect-adf.sh amix_21_root.adf
detected disk type : root
-> UFS miniroot; expect m68k ELF installer binaries + install shell scripts
[xdftool] ...
'list' FSError: Invalid Boot Block(1):block=BootBlock:@0
That Invalid Boot Block @0 is expected and correct — it confirms there is no AmigaDOS filesystem. The body is instead an SVR4 s5 filesystem, with its superblock at byte 0x200 (magic 0xfd187e20) ✅ — see the 2026-07-05 correction at the top of this page. The UFS miniroot line the tool prints is wrong: inspect-adf.sh classifies by keying off the lost+found string, and lost+found plus the fsck/mkfs string tables are present here because the floppy carries the UFS tools as installer binaries, not because it is a UFS volume ✅ (see tools/inspect-adf.sh lines 59–63). It is a good worked example of why a string heuristic is not a filesystem identification.
Note — reading the tree. The body is s5, so a full file-tree traversal needs an s5-aware filesystem reader, not a UFS one (see the install script below). The bundled tools/unpack-root.sh does a pragmatic carve instead: it reports every ELF/script offset, carves the POSIX tar member(s), and dumps the install-script text — which is what you usually want when studying the installer. ✅
What's inside: installer ELF binaries, scripts, and a tar member¶
binwalk finds roughly 30 m68k ELF executables interleaved with two /bin/sh scripts and one POSIX tar member. ✅ The first object sits at offset 0x6800 (26624):
DECIMAL HEXADECIMAL DESCRIPTION
26624 0x6800 ELF, 32-bit MSB executable, Motorola 68020, version 1 (SYSV)
26836 0x68D4 Unix path: /usr/lib/libc.so.1
29859 0x74A3 Unix path: /dev/rmt/4h
31802 0x7C3A Unix path: /dev/rmt/4hn bs=256k|cpio -imdcu
31894 0x7C96 Unix path: /dev/rmt/4hn bs=256k | zcat | cpio -imdcu %s
...
94592 0x17180 POSIX tar archive
217088 0x35000 Executable script, shebang: "/bin/sh"
218112 0x35400 Executable script, shebang: "/bin/sh"
binwalk amix_21_root.adf)
The first-ELF header confirms the binary format used throughout the installer: ✅
$ dd if=amix_21_root.adf bs=1 skip=26624 count=20 2>/dev/null | xxd
00000000: 7f45 4c46 0102 0100 0000 0000 0000 0000 .ELF............
00000010: 0002 0004 ....
Decoded: 7f 45 4c 46 = ELF magic; 01 = ELFCLASS32; 02 = ELFDATA2MSB (big-endian); 01 = version; type 0x0002 = ET_EXEC; machine 0x0004 = EM_68K. Every installer binary references /usr/lib/libc.so.1 — i.e. these are dynamically-linked SVR4 m68k executables, not static blobs. ✅
The installer binaries you can fingerprint by their embedded usage/command strings include: ✅
| Binary (referenced path) | Role in the install |
|---|---|
/bin/cpio |
Unpacks the distribution stream from tape |
fsck_s5, fsck_ufs |
Filesystem check, per FS type |
mkfs_s5, mkfs_ufs |
Create an s5 or UFS filesystem |
dd |
Reads the raw tape device (/dev/rmt/4hn) |
/etc/rdb |
Reads/writes the Rigid Disk Block partition table |
/etc/atdevs, /etc/ddsize |
SCSI bus scan; partition size in 512-byte blocks |
amixpkg |
SVR4 package install wrapper (-b, -i, …) |
mount / umount / swap |
Mount the new root, add swap |
viper_kludge |
Tape-drive kernel patch (see below) |
The two /bin/sh scripts at 0x35000/0x35400 are the install driver — the partition/filesystem logic dissected in the next section. Note that Amix's /bin/sh is pre-POSIX (no $(...), no grep -q), so the scripts use back-ticks, expr, and set -- throughout. ✅ (root.adf script text; the pre-POSIX /bin/sh limitation is corroborated by the VA2000 driver case study.)
The tar member at 0x17180 is a POSIX (ustar) archive; carve it with unpack-root.sh (it stops at the archive's own end-of-archive marker) for offline inspection. ✅
The install script is /etc/profile¶
The install driver is not an anonymous blob you have to carve out of the image — inside the miniroot's s5 filesystem it lives at the path /etc/profile ✅ (first-party, 2026-07-31: read out of the stock root floppy by path with an s5-aware filesystem reader). The placement is the launch mechanism: a Bourne login shell reads /etc/profile at startup, so the miniroot needs no separate installer hook — the install kernel mounts the floppy, spawns the shell, and sourcing the profile starts the installer. Practically, this means you no longer need the offset-carve above to study the installer: any tool that can walk the s5 filesystem inside the ADF (see the 2026-07-05 s5 correction at the top of this page) extracts the script byte-exact by its path. And it makes /etc/profile the authority for every /etc/rdb, mkfs, and partition-arithmetic question — it is the code every stock install actually runs. Its exact command lines, and the unit conventions they prove, are dissected on the filesystems & disks page.
Two identity facts to pin while the image is open ✅ (first-party, 2026-07-31):
/etc/rdbon this floppy is 18,416 bytes, md56cacf95f738abea7cfddc6bb9ebf28e7.- A rebuilt install miniroot (the Installer-NG media) carries a byte-identical copy of that binary — so
rdbbehaviour proven against the rebuilt media is the stock binary's behaviour, and vice versa. That identity is what transfers the bench-proven unit conventions on the filesystems page to the stock installer.
The install / partition logic¶
The install script computes a default partition layout, lets you override it, then writes the Rigid Disk Block and creates filesystems. The tunables at the top of the script are exact: ✅ (root.adf script text)
BREAKPT=120 # Larger default swap when disk is over BREAKPT mb in size
LGSWAP=30 # Suggested size of swap area, mb, for "large" disks
SMSWAP=18 # Suggested size of swap area, mb, for "small" disks
MINBOOT=2 # Minimum size of bootstrap partition in megabytes
BOOTSIZE=2 # Default bootstrap partition size
UFS_OPT="-o free=2,opt=s" # options for mkfs_ufs
Key behaviours encoded here:
- Boot/bootstrap partition = 2 MB.
BOOTSIZE=2andBOOTLEN=expr $BOOTSIZE '*' 2048`` ⇒ a 2 MB partition is 4096 blocks of 512 bytes. This is the small partition that holds the relocatable kernel the Superkickstart ROM boots. ✅ - Swap scales with disk size. Disks larger than
BREAKPT=120MB getLGSWAP=30MB of swap; smaller disks getSMSWAP=18MB. ✅ - The tape ID is fixed; the disk ID is prompted. The tape is always id 4 — the disk-selection loop explicitly rejects that target as tape-only: ✅
The install script uses a $SCSI variable for the disk, so the prompt accepts other target ids — ID 6 is a strong convention, not a kernel mandate 🟡. In practice, use id 6 for the disk: whatever target you pick is baked into the device names (c${SCSI}d0s…) written into /etc/vfstab (the SVR4 mount table) and the boot partition, so changing it after install means editing those by hand. (The tape, by contrast, is genuinely fixed at id 4 — the scripts hard-reference /dev/rmt/4h.) See the quirks page and hardware.
- Device paths are templated on the chosen SCSI id. After partitioning, the script binds: ✅
UPART=/dev/dsk/c${SCSI}d0s${ROOTPART} # root
SPART=/dev/dsk/c${SCSI}d0s${SWAPPART} # swap
BPART=/dev/dsk/c${SCSI}d0s${BOOTPART} # boot/bootstrap
EPART=/dev/dsk/c${SCSI}d0s${EXTRAPART} # optional extra
Filesystem choice: s5 vs UFS¶
For each data partition the script asks: ✅
Choose a file system type for this partition:
s5: Traditional UNIX file system
ufs: Berkeley file system
What file system type is this partition? [s5]
The prompt shows [s5] as the bracketed default, and community guidance — and the brief — recommends UFS in practice; the s5 default is plausibly a 3B2-lineage hold-over. 🟡 (rationale unconfirmed). Both the per-partition and the root prompt default to s5; ANS="ufs" is set only when ufs is typed ✅ (see filesystems & disks).
There is one exception the script can enforce for the root partition: ✅
Here the script overrides the s5/ufs choice back to s5, with the comment that the "Johann ROM" can only boot an s5 root. ✅ (root.adf script text; the "Johann" name appears verbatim in the installer comment; its relationship to the Superkickstart boot ROM is 🔴 unconfirmed in the research brief — see the boot process.)
Scope correction (2026-08-14). That force is not unconditional: it is reached only on the stock OLD_BOOT / Johann-ROM path ✅. It is therefore not the reason a given disk is s5 — a modern install path can and does produce a UFS root, and the surviving 2.1 install lineage examined by this project is UFS-rooted (superblock fingerprint -o free=2,opt=s, 8192/8) ✅. What actually makes the typical root s5 is the plain [s5] prompt default above, not this override. And nothing in the kernel insists either way — root filesystem selection is by probe, not by configuration.
RDB partition type tags¶
After laying out the partitions with /etc/rdb -a, the script stamps each one with an SVR4/Amix partition type tag via /etc/rdb -F (this resolves brief gap #8, the previously-undocumented RDB type IDs — values read directly from the installer): ✅
/etc/rdb -p $BOOTPART -M -B -C 2 -P 2 -F 0x554e4900 $DISK # 'UNI\0' bootable boot partition
/etc/rdb -p $ROOTPART -m -F 0x554e4901 $DISK # 'UNI\1' UNIX root
/etc/rdb -p $SWAPPART -m -F 0x72657376 $DISK # 'resv' swap
The script's own comment is explicit about why the boot partition must be 0x554e4900: ✅
# The Kickstart 2.04 booting priority algorithms require that bootable
# UNIX partitions are filesystem type 0x554e4900. Other types may [not boot]
So: boot partition type 0x554e4900 (ASCII UNI\0), UNIX root 0x554e4901 (UNI\1), swap 0x72657376 (resv). The -B/-C 2/-P 2 flags mark the partition bootable with the boot-priority/auto-mount fields the ROM scans. ✅
Driving the package install¶
Once partitions and filesystems exist and the new root is mounted at /mnt, the script computes how much space is available and calls amixpkg: ✅
amixpkg -b -v -r /mnt $OPTIONS || # bootstrap pass
amixpkg -i -m -d -r /mnt -y standard -s $AVAILABLE || # install "standard" cluster
-r /mnt is the alternate root, -y standard selects the standard package cluster, and -s $AVAILABLE caps the install to the free blocks computed from the root partition. The amixpkg wrapper is widely reported as flaky, but the miniroot install path relies on it. 🟡 (amixpkg reliability)
The tape distribution pipeline¶
The actual operating-system files do not live on the root floppy — they are streamed from a QIC tape at SCSI id 4 and unpacked through cpio. The script defines the tape devices and the pipelines verbatim: ✅
The distribution is read with dd and fed to cpio. Two variants appear, depending on whether the tape image is compressed: ✅
dd if=/dev/rmt/4hn bs=256k | cpio -imdcu # plain cpio stream
dd if=/dev/rmt/4hn bs=256k | zcat | cpio -imdcu # compress(1)-ed stream
cpio flags here: -i extract, -m retain modification times, -d create directories, -c ASCII header, -u unconditional overwrite. A cpio -imdcuB < /dev/rmt/4hn > /dev/null invocation also appears (the B = 5120-byte block size for raw tape), used to verify/seek the tape. ✅
The device-naming convention (/dev/rmt/<id><density>[n], n = no-rewind) is part of the SVR4 tape model; the 4 is the hard-coded SCSI tape id. See the device list and the quirks page.
Tape-free installs. Because most emulator users have no real QIC drive, the practical path is to present a tape image at SCSI id 4 in the emulator, or to dd a cpio image to swap from Linux/AmigaDOS and extract with cpio. The latter is documented on comp.unix.amiga. 🟡 See emulation on WinUAE for the SCSI-id-4 tape-image setup and the install walkthrough.
viper_kludge: the non-standard-tape work-around¶
The root floppy ships viper_kludge (an m68k ELF) and its /viper.README, written by Frank "Crash" Edwards. Its purpose is to patch kernel memory at install time so that tape drives the Amix kernel does not natively know — specifically the Archive Viper 2150S — can be read by dd/cpio during the install. ✅ (root.adf strings; viper.README)
When you'd use it. If the install fails with a tape I/O error on a non-standard drive, you press Ctrl-D until you reach the interactive # prompt, then run viper_kludge with no arguments to read its on-screen warning, and finally viper_kludge go to apply the patch. The viper.README walks through this. ✅
It is dangerous — heed the built-in warnings. Both the runtime banner and viper.README warn, verbatim: ✅
- "THIS PROGRAM (viper_kludge) IS EXPERIMENTAL. BY RUNNING IT THE USER AGREES TO BEAR ALL RESPONSIBILITY FOR THE RESULTS."
- It is incompatible with, and must not be run on systems using, the Commodore A3070, Caliper, Wangtek, and Sankyo 150 MB cartridge drives — "It PREVENTS their use". ✅
- The patch lives only in RAM: "Shutting down and rebooting removes the kernel memory patch." So it must be re-applied per boot until a real driver is built. ✅
- For a permanent fix, the README points at "the files in directory
/usr/sys/amiga/alien/contrib" to make the kernel inherently recognise the Viper — i.e. building tape support into the kernel rather than patching live memory. ✅ (cf. the kernel-rebuild flow in kernel build & install)
Bottom line: only use viper_kludge if you have a genuinely unsupported tape drive and the standard install has already failed on a tape error. If your drive is an A3070 or any Caliper/Wangtek/Sankyo unit, do not run it.
Tooling: inspecting and unpacking the root floppy¶
Both scripts are read-only on the input image and operate on your own copy of the ADF.
tools/inspect-adf.sh — classify the disk and surface the installer / tape / partition strings: ✅
tools/inspect-adf.sh amix_21_root.adf
# detected disk type : root
# -> UFS miniroot; expect m68k ELF installer binaries + install shell scripts
# [root] installer / tape pipeline strings:
# amixpkg -i -m -d -r /mnt -y standard -s $AVAILABLE ||
# BOOTSIZE=2 # Default bootstrap partition size
# BPART=/dev/dsk/c${SCSI}d0s${BOOTPART}
# dd if=/dev/rmt/4hn bs=256k | zcat | cpio -imdcu %s
# ... viper_kludge ...
tools/unpack-root.sh — scan, carve the tar member(s), and dump the install-script text into tools/_work/<image>/ (gitignored): ✅
tools/unpack-root.sh amix_21_root.adf
# == unpack-root: amix_21_root.adf -> tools/_work/amix_21_root =
# -- scanning for embedded objects (binwalk) --
# -- carving POSIX tar member(s) --
# carved .../tar_1_at_94592.tar (from offset 94592)
# -- installer script text (high-value strings) -- (full dump in strings.txt)
Both require binwalk/strings; inspect-adf.sh additionally uses xdftool (from amitools) and xxd when present and degrades gracefully otherwise.
See also¶
- Install walkthrough — the end-to-end procedure that uses this floppy.
- Anatomy of the boot floppy — the bootable disk that loads the install kernel before you swap in the root floppy.
- Anatomy of the patch floppy — the self-extracting 2.1c patch disk.
- The build pipeline — how the boot/root/patch disks are produced and how to build add-on disks.
- Filesystems and disks — RDB scheme, s5 vs UFS, partition layout.
- Quirks — the SCSI ids (tape fixed at 4, disk 6 by convention), the RAM limits, and other landmines.
Sources¶
amix_21_root.adfanalysis viatools/inspect-adf.shandtools/unpack-root.sh—binwalkobject table (30 m68k ELF objects, first at 0x6800;tarmember at 0x17180;/bin/shscripts at 0x35000/0x35400), ELF header bytes at 0x6800 (ELFCLASS32,ELFDATA2MSB,ET_EXEC,EM_68K), andstringsdump of the install script (BOOTSIZE/BREAKPT/LGSWAP/SMSWAP,BPART/UPART/SPART, s5/ufs prompts (both[s5]; empty input →ANS="s5",ANS="ufs"only on typedufs),ROOT_FSYS="s5" # Johann ROM, RDB-Ftype tags0x554e4900/0x554e4901/0x72657376,amixpkginvocations,/dev/rmt/4hntape pipelines).viper.READMEand theviper_kludgeruntime banner extracted fromamix_21_root.adf(author Frank "Crash" Edwards; incompatibility with A3070/Caliper/Wangtek/Sankyo; RAM-only patch; pointer to/usr/sys/amiga/alien/contrib).- Master research brief, §9 (installation flow) and §10 (root.adf anatomy); §2 (SCSI ids — tape hard-coded at 4, disk 6 by convention; RAM ceiling); §13 gap #8 (RDB partition type IDs).
- SHA-256 cross-check:
sources/CHECKSUMS.txt. - Disk image (not redistributed here): amigaunix.com / archive.org Amiga UNIX.
- The Installer-NG author-path proof (not public, 2026-07-31) ✅ — the stock root floppy's install script read by path (
/etc/profile) with an s5 filesystem reader, matching the carved script text above;/etc/rdbmd56cacf95f738abea7cfddc6bb9ebf28e7(18,416 B), byte-identical between the stock floppy and the rebuilt install miniroot.