amiga-bootcamp/06_exec_os/exec_base.md
2026-06-02 11:57:54 -04:00

8.2 KiB
Raw Blame History

← Home · Exec Kernel

ExecBase — Full Structure Reference

Overview

ExecBase is the root structure of AmigaOS, located at absolute address $4. It is a struct Library extended with all exec kernel state: memory lists, task queues, interrupt vectors, library lists, and hardware abstraction fields. Every system call goes through ExecBase — it is the single point of truth for the entire running system.


Locating ExecBase

/* C — standard method */
struct ExecBase *SysBase = *((struct ExecBase **)4);

/* Or use the auto-open variable (SAS/C, GCC): */
extern struct ExecBase *SysBase;  /* Linker resolves from startup code */
; Assembly — canonical method
    MOVEA.L  4.W,A6    ; A6 = SysBase (short absolute addressing)
    ; All exec LVO calls use JSR offset(A6)

Why address $4? The 68000 stores the initial Program Counter at address $4 in the exception vector table. During cold boot, the CPU reads this address to find the ROM entry point. After boot, Exec overwrites it with a pointer to ExecBase. This is the one absolute address every Amiga program can rely on.


Structure Layout

graph TB
    EB["ExecBase at $4"] --> LIB["Library Header<br/>(struct Library)<br/>Offsets 033"]
    EB --> SOFT["Software Config<br/>SoftVer, ColdCapture,<br/>WarmCapture, SysStkUpper"]
    EB --> TASK["Task Scheduling<br/>TaskReady, TaskWait,<br/>ThisTask, IDNestCnt,<br/>TDNestCnt, Quantum"]
    EB --> MEM["Memory Management<br/>MemList, MaxLocMem,<br/>MaxExtMem"]
    EB --> LISTS["System Lists<br/>LibList, DeviceList,<br/>ResourceList, PortList,<br/>IntrList"]
    EB --> HW["Hardware Detection<br/>AttnFlags, ChipRevBits0,<br/>PowerSupplyFrequency,<br/>VBlankFrequency"]

    style EB fill:#e8f4fd,stroke:#2196f3,color:#333
    style TASK fill:#e8f5e9,stroke:#4caf50,color:#333
    style HW fill:#fff3e0,stroke:#ff9800,color:#333

Key Field Groups

Library Header (Offset 033)

Every library starts with this — ExecBase is exec.library's own base:

struct Library  LibNode;     /* ln_Name = "exec.library" */
                             /* lib_Version = 40 (OS 3.1), 45 (OS 3.2), 47 (OS 3.2.2) */
                             /* lib_OpenCnt = open count */

Boot and Configuration

Offset Field Type Description
$22 SoftVer UWORD Kickstart software revision
$24 LowMemChkSum WORD Checksum of vectors $0$200
$26 ChkBase ULONG ExecBase self-checksum
$2A ColdCapture APTR Cold reboot intercept vector
$2E CoolCapture APTR Warm reboot intercept vector (after Diag)
$32 WarmCapture APTR Keyboard reset intercept vector
$36 SysStkUpper APTR Top of supervisor stack
$3A SysStkLower APTR Bottom of supervisor stack
$3E MaxLocMem ULONG Top of Chip RAM (e.g., $200000 for 2 MB)
$42 DebugEntry APTR Entry point for ROM debugger (Wack)
$46 DebugData APTR Data area for ROM debugger
$4A AlertData APTR Last Alert data
$4E MaxExtMem APTR Top of Extended RAM (or NULL)

Task Scheduling

Offset Field Type Description
$126 IDNestCnt BYTE Interrupt disable nesting (1 = enabled)
$127 TDNestCnt BYTE Task disable nesting (1 = enabled)
$128 ThisTask APTR Pointer to currently running Task
$12C Quantum UWORD Time slice for equal-priority round-robin
$12E Elapsed UWORD Ticks elapsed in current quantum
$130 SysFlags UWORD Internal scheduler flags
$132 TaskReady List Tasks ready to run (sorted by priority)
$146 TaskWait List Tasks blocked on Wait()

Memory

Offset Field Type Description
$15A MemList List All memory regions (MemHeader chain)

System Lists

Offset Field Type Description
$17A LibList List Loaded libraries (NT_LIBRARY)
$18E DeviceList List Loaded devices (NT_DEVICE)
$1A2 IntrList List Interrupt server lists
$1B6 ResourceList List System resources
$1CA PortList List Public message ports
$1DE SemaphoreList List Public semaphores

Hardware Detection

Offset Field Type Description
$128 AttnFlags UWORD CPU and FPU capability flags
$212 VBlankFrequency UBYTE VBL rate: 50 (PAL) or 60 (NTSC)
$213 PowerSupplyFrequency UBYTE Mains: 50 or 60 Hz
$21E ChipRevBits0 UBYTE Chip revision detection

AttnFlags — CPU Detection

Bit Constant Meaning
0 AFF_68010 68010 or better detected
1 AFF_68020 68020 or better
2 AFF_68030 68030 or better
3 AFF_68040 68040 or better
4 AFF_68881 68881 FPU detected
5 AFF_68882 68882 FPU detected
6 AFF_FPU40 68040 internal FPU
7 AFF_68060 68060 detected (OS 3.1+)
10 AFF_PRIVATE Exec private — do not use

Usage

/* Check for 68020+ */
if (SysBase->AttnFlags & AFF_68020)
{
    /* Can use CACHE instructions, 32-bit multiply, etc. */
}

/* Check for FPU */
if (SysBase->AttnFlags & (AFF_68881 | AFF_68882 | AFF_FPU40))
{
    /* Floating-point hardware available */
}

Detecting Chipset Revision

/* via graphics.library */
struct GfxBase *gfx = (struct GfxBase *)OpenLibrary("graphics.library", 36);
if (gfx)
{
    if (gfx->ChipRevBits0 & GFXB_AA_ALICE)  /* AGA Alice */
    if (gfx->ChipRevBits0 & GFXB_AA_LISA)   /* AGA Lisa */
    if (gfx->ChipRevBits0 & GFXB_HR_AGNUS)  /* ECS Agnus */
    if (gfx->ChipRevBits0 & GFXB_HR_DENISE) /* ECS Denise */
}

Enumerating System Lists

Walking the Library List

Forbid();
struct Node *node;
for (node = SysBase->LibList.lh_Head;
     node->ln_Succ != NULL;
     node = node->ln_Succ)
{
    struct Library *lib = (struct Library *)node;
    Printf("  %s V%ld.%ld (open: %ld)\n",
        lib->lib_Node.ln_Name,
        lib->lib_Version,
        lib->lib_Revision,
        lib->lib_OpenCnt);
}
Permit();

Walking the Task Lists

Forbid();

/* Currently running */
Printf("Running: %s\n", SysBase->ThisTask->tc_Node.ln_Name);

/* Ready to run */
for (node = SysBase->TaskReady.lh_Head;
     node->ln_Succ; node = node->ln_Succ)
{
    Printf("  Ready: %s (pri %ld)\n",
        node->ln_Name, node->ln_Pri);
}

/* Waiting */
for (node = SysBase->TaskWait.lh_Head;
     node->ln_Succ; node = node->ln_Succ)
{
    Printf("  Wait:  %s (pri %ld)\n",
        node->ln_Name, node->ln_Pri);
}

Permit();

ExecBase Safety Rules

Rule Reason
Never write to ExecBase fields Corrupts kernel state for all tasks
Use Forbid() when walking lists Lists change as libraries open/close, tasks start/stop
Don't cache pointers from lists Nodes may be removed between accesses
Always use LVO functions Direct field manipulation bypasses safety checks
Verify SysBase after warm reboot ColdCapture/CoolCapture may have altered it

ExecBase in IDA Pro / Ghidra

After loading Kickstart ROM:

  1. Create a segment at $000000$000400 (exception vectors)
  2. Mark $4 as a pointer — follow it to the ExecBase in ROM
  3. Apply struct ExecBase type from NDK39 headers
    • IDA: File → Parse C header with exec/execbase.h
    • Ghidra: Import C headers via Data Type Manager
  4. All N(A6) offsets in exec code auto-annotate as field names
  5. Label the system listsLibList, DeviceList, PortList are entry points for understanding boot order

References

  • NDK39: exec/execbase.h — authoritative field definitions
  • ADCD 2.1: exec.library autodoc
  • See also: Library System — how libraries relate to ExecBase
  • See also: Multitasking — TaskReady/TaskWait and scheduler internals
  • See also: Kickstart Boot Diagnostics — ColdStart ExecBase allocation, chip RAM sizing
  • Amiga ROM Kernel Reference Manual: Exec — ExecBase chapter