Details for Magic‐1 Bootloader - retrotruestory/M1DEV GitHub Wiki

Critical Technical Details for Magic-1 Bootloader

The Magic-1 bootloader (bloader) serves as the initial program that sets up the hardware environment and loads the operating system. Here are the critical technical details necessary for understanding and working with it:

Architecture Fundamentals

  • Memory Model: Magic-1 uses a segmented memory model with separate code and data page tables
  • Page Size: 2KB (2048 bytes) per page
  • Addressing: 22-bit physical address space (effectively 23-bit with device space)
  • Page Table Structure: Each process has 64 16-bit page table entries (32 for code, 32 for data)
  • Endianness: Big-endian architecture (as noted in comments: "little-endianness is the mark of Satan")

Page Table Flags

#define PAGE_PRESENT       0x8000  // Valid page (must be set)
#define PAGE_NOT_PRESENT   0x0000  // Invalid/unmapped page
#define PAGE_WRITEABLE     0x4000  // Enable write access
#define PAGE_NOT_WRITEABLE 0x0000  // Read-only access
#define PAGE_SRAM          0x2000  // Access physical SRAM
#define PAGE_DEVICE        0x0000  // Access hardware device memory
#define PAGE_WAIT          0x0000  // Wait states enabled
#define PAGE_NO_WAIT       0x1000  // No wait states (faster)

Memory Organization

  • Boot ROM: Initial code runs from ROM with limited memory access
  • Device SRAM: Limited RAM available during early boot (stack at 0x8000)
  • Memory-mapped I/O:
    • UART ports: 0xFFF0 (primary), 0xFFE0 (secondary)
    • RTC: 0xFFD0 (real-time clock)
    • IDE/CF controllers: 0xFF80-0xFFBF
    • POST code: 0xFFC0 (diagnostic output)
    • Switches: 0xFFA0 (front panel controls)

Boot Process

  1. Power-on state:

    • Interrupts disabled
    • Supervisor mode
    • Paging disabled
    • Code running from ROM
    • Stack in device SRAM
  2. Setup phase:

    • Initialize serial ports
    • Configure page tables
    • Set up memory mapped I/O
    • Detect storage devices
  3. Storage initialization:

    • Support for up to 3 drives: IDE Master, IDE Slave, CF Master
    • Uses busy-wait I/O (no interrupts)
  4. Boot Image Management:

    • Supports up to 8 bootable images
    • Images stored in image_table with metadata
    • Can be loaded from disk sectors
  5. Address Space Setup:

    • OS code loaded to physical memory 0x00000-0x0FFFF
    • Data loaded to 0x10000-0x1F800
    • Special mapping for device pages (0xF800-0xFFFF)

Critical Functions

Memory Management

// Page table manipulation
void write_code_pte(unsigned int address, unsigned int value);
void write_data_pte(unsigned int address, unsigned int value);
void set_pid(unsigned int pid);
void paging_on();
void paging_off();

// Memory transfers between spaces
void sys_to_user_space(char *tgt, char *src, unsigned int size);
void user_to_sys_space(char *tgt, char *src, unsigned int size);

Boot Transition

The most critical and complex function in the bootloader is do_boot0(), which:

  1. Disables paging (memory values disappear)
  2. Creates a new supervisor page table mapping to the loaded OS
  3. Sets up a dummy save state on stack
  4. Transfers control to OS at 0x0000 via reti instruction
; Simplified excerpt of key code in do_boot0
copy    a,msw
and.16  a,0xFF7F        ; Disable paging
copy    msw,a           ; Memory now gone, running from ROM

; After remapping page tables:
push    a               ; MSW with paging on, interrupts off
push    b               ; SP
push    b               ; PC (0x0000)
; ...more registers...
reti                    ; Transfer control to OS

Storage System Details

  • Sector size: 512 bytes
  • Interface types: IDE and Compact Flash
  • Busy-wait I/O: All operations use polling, not interrupts
  • Error handling: Automatic reset on errors with comprehensive error codes

Special Implementation Notes

  1. Paging transition handling: When toggling paging on/off, memory locations may become inaccessible. Functions like _paging_on() must save return addresses in registers.

  2. Split vs. Unified address spaces: The bootloader supports both models:

    • Split: Separate code and data spaces
    • Unified: Data pages map to code space
  3. Intel Hex loading: Supports loading programs in Intel Hex format with special handling for split/unified images.

These details provide the essential knowledge required to understand, maintain, or modify the Magic-1 bootloader.