AmigaDOS Library Internals

This article covers the data structures that dos.library keeps around itself: the library base, the RootNode it points at, the DosInfo that the RootNode points at, and the boot process that ties everything together. Most of this state is library-private; documented here for understanding rather than for direct manipulation.

Do not read or write these structures from application code. Use the accessor functions (FindCliProc(), LockDosList(), FindSegment(), DateStamp(), Fault(), etc.). The on-disk layout of the structures has changed between releases and will change again.

The DosLibrary base

dos.library's library base extends the standard struct Library with a handful of DOS-specific fields:

struct DosLibrary {
    struct Library       dl_lib;            /* standard exec library header */
    struct RootNode     *dl_Root;           /* pointer to the RootNode */
    APTR                 dl_GV;             /* BCPL Global Vector (legacy) */
    LONG                 dl_A2;             /* BCPL runtime initializer */
    LONG                 dl_A5;             /* BCPL runtime initializer */
    LONG                 dl_A6;             /* BCPL runtime initializer */
    /* V36+ */
    struct ErrorString  *dl_Errors;         /* localized error-message table (private) */
    struct timerequest  *dl_TimeReq;        /* timer.device IORequest (private) */
    struct Library      *dl_UtilityBase;    /* cached utility.library */
    struct Library      *dl_IntuitionBase;  /* cached intuition.library */
};
Field Meaning
dl_lib Standard exec library header (the rest of dos.library reads as struct Library *).
dl_Root Pointer to the RootNode — created with the library and never changes.
dl_GV BCPL Global Vector for BCPL callers. No current AmigaDOS component should depend on it — equivalent functions are accessible as dos.library calls.
dl_A2 / dl_A5 / dl_A6 BCPL runtime initializers; obsolete.
dl_Errors Localized message strings. Private. Use Fault() instead.
dl_TimeReq A cached timerequest used by DateStamp(), Delay(). Private.
dl_UtilityBase / dl_IntuitionBase Cached library bases for utility.library (tag-list parsing) and intuition.library (requesters).

The ErrorString table

struct ErrorString {
    LONG *estr_Nums;       /* [lower, upper] inclusive range of codes */
    UBYTE *estr_Strings;   /* concatenated length-prefixed strings */
};

dl_Errors points to an array of ErrorString. Each entry covers a range [lo, hi] of message codes; the array ends when lo == 0. The strings are stored as [length+1, bytes…, NUL] — the length byte includes the NUL. Linear scan; ignore it and use Fault().

The RootNode

Created during dos.library initialization, persistent for the system's life. Reachable via dos.library->dl_Root.

struct RootNode {
    BPTR                rn_TaskArray;             /* BPTR to first CliProcList array (legacy) */
    BPTR                rn_ConsoleSegment;        /* "CLI" resident segment (obsolete) */
    struct DateStamp    rn_Time;                   /* current time, updated by DateStamp() */
    LONG                rn_RestartSeg;            /* OBSOLETE — was disk validator segment */
    BPTR                rn_Info;                  /* BPTR to DosInfo */
    BPTR                rn_FileHandlerSegment;   /* ROM FFS segment (obsolete) */
    /* V36+ */
    struct MinList      rn_CliList;               /* all CliProcList nodes */
    struct MsgPort     *rn_BootProc;              /* MsgPort of the boot filesystem */
    BPTR                rn_ShellSegment;          /* "Shell-Seg" segment (obsolete) */
    LONG                rn_Flags;                 /* RNF_WILDSTAR etc. */
};
Field Notes
rn_TaskArray BPTR to the first element of the (legacy) CLI table — a LONG count followed by count MsgPort * pointers to pr_MsgPort of shell processes. Indexed by CLI number. The array is also reachable as cpl_Array[0] of the first CliProcList node. Use FindCliProc() — never index this directly.
rn_ConsoleSegment BPTR to the BCPL "CLI" segment. No longer used (V47 uses FindSegment("CLI")).
rn_Time Updated on every DateStamp() call. Read via DateStamp(), not directly.
rn_RestartSeg Obsolete; was the disk-validator segment in pre-V34.
rn_Info BPTR to the DosInfo.
rn_FileHandlerSegment BPTR to the ROM FFS segment. Use FileSystem.resource instead — only expansion.library/AddDosNode() still touches this.
rn_CliList MinList of CliProcList nodes. Use FindCliProc() / MaxCli().
rn_BootProc MsgPort of the boot filesystem. Used to seed pr_FileSystemTask of every process AmigaDOS creates (i.e., the FS behind the ZERO lock).
rn_ShellSegment BPTR to the shell segment ("Shell-Seg" from disk or ROM). Not used in V47 — FindSegment("shell") is.
rn_Flags One public flag: RNF_WILDSTAR. If set, the pattern matcher treats * as a synonym for #?. Not recommended — * is also the name of the current console and the Shell escape character.

CliProcList (the CLI table extension)

struct CliProcList {
    struct MinNode    cpl_Node;
    LONG              cpl_First;     /* CLI number of the first entry in this node */
    struct MsgPort  **cpl_Array;     /* [0] = count (typically 20), [1..count] = MsgPort * */
};

CliProcList is how V36+ extends the legacy 20-entry CLI table. The first CliProcList is also reachable as rn_TaskArray. New nodes are appended when the table runs out of room (e.g., on launching many shells via System() / Execute()). Do not allocate these yourself.

The DosInfo structure

Reachable via rn_Info.

struct DosInfo {
    BPTR                   di_McName;       /* also known as di_ResList — UNUSED */
    BPTR                   di_DevInfo;      /* head of the device list (chapter 8) */
    BPTR                   di_Devices;      /* TRIPOS legacy, unused */
    BPTR                   di_Handlers;     /* TRIPOS legacy, unused */
    APTR                   di_NetHand;      /* actually a BPTR; head of resident-segment list */
    /* V36+ */
    struct SignalSemaphore di_DevLock;      /* private; backs LockDosList() */
    struct SignalSemaphore di_EntryLock;    /* private */
    struct SignalSemaphore di_DeleteLock;   /* private */
};
Field Meaning
di_McName (di_ResList) Despite the alias suggesting "resident segment list", this field is unused.
di_DevInfo Head of the device list — see The AmigaDOS Device List. Iterate via NextDosEntry() / FindDosEntry(), not by walking this list directly.
di_Devices, di_Handlers Tripos leftovers; no current AmigaDOS reads them.
di_NetHand Despite the APTR type in the includes, this is a BPTR to the head of the resident-segment list (Ch. 15.6). Iterate via FindSegment() / NextSegment().
di_DevLock, di_EntryLock, di_DeleteLock Private semaphores backing LockDosList() / AttemptLockDosList() / UnLockDosList().

The AmigaDOS boot process

The kickstart-resident strap module locates the boot volume (via boot-point or boot-block code on the host adapter or floppy). It then runs the dos.library resident module via InitResident(). From that point:

  1. dos.library builds a minimal instance of itself — many resources are still missing.
  2. Pre-V47: the boot shell runs CliInit() to finish initialization (open boot console, mount devices, run S:Startup-Sequence).
  3. V47+: dos.library finds the System-Startup resident module and starts a dedicated process from it. That process completes initialization, then launches the boot shell via System().

The System-Startup module (V47+)

System-Startup is the rough equivalent of Unix init. It performs the following in order:

  1. Allocates and initializes the DosInfo, then sets up rn_CliList in the RootNode.
  2. Transfers autoboot DosList entries from expansion.library to dos.library's device list (this mounts boot devices). The first one becomes the boot volume.
  3. Locates the FFS — first as the ROM filesystem resident, then upgrades from the RDB if a newer FFS is available there. Creates a FileHandler resident segment and links it into DosInfo.
  4. Starts the boot volume's filesystem, then the remaining filesystems.
  5. Mounts the system assigns (L:, FONTS:, DEVS:, LIBS:, S:, C:, SYS:, ENVARC: — ENVARC: is a late-binding assign to SYS:Prefs/Env-Archive).
  6. Mounts PRT:, PAR:, SER:, PIPE: (Port-Handler devices).
  7. Mounts CON: / RAW: (CON-Handler) and RAM: (RAM-Handler), upgrading from L: if a newer disk-based version is found.
  8. Locates the boot shell (shell resident, or L:Shell-Seg). Creates the CLI, BootShell, and shell resident segments from it.
  9. Performs ROM Updates: scans LIBS:, DEVS: and (since v47) intuition.library for newer versions, tears down the resident, and installs the disk-based version. Libraries being torn down are alerted and patched to Alert() until replaced.
  10. Enables AGA extensions if the boot menu ran in 31 kHz DblPAL / DblNTSC.
  11. Initializes resident modules of lower priority than dos.library flagged RTF_AFTERDOS (e.g., audio.device, mathffp.library).
  12. Loads DEVS:System-Configuration and installs the preferences into intuition (legacy; still affects boot-console colour and pointer).
  13. Opens the boot console in AUTO mode (window opens only when something is actually written).
  14. Opens S:Startup-Sequence as the shell's command stream.
  15. Detects the boot protocol (V36+ vs. legacy) — older boot blocks force the console open with a \r and set the boot shell's cwd to the ZERO lock for compatibility. V36+ sets it to the root of the boot volume (SYS:).
  16. If boot-menu "logging" was on, starts the syslog process that mirrors RawPutChar() to RAM:syslog and sets the debug shell variable.
  17. If boot-menu "tracing" was on, sets the interactive shell variable.
  18. Launches the InitialCLI / Boot Shell via System(). With S:Startup-Sequence as command stream (unless disabled in the boot menu). The System-Startup process then terminates.

Filesystem authors: do not cache IntuitionBase. In V47 ROM-Update can tear down intuition.library mid-operation; always OpenLibrary() it on demand.

See Also


Sources: Thomas Richter, "ROM Kernel Reference Manual: AmigaDOS" (First Edition, 2024), Chapter 17 — The DOS Library. Raw: raw/rkm/rkm-dos-book.md Updated: 2026-10-02