Magic‐1 Computer Bootloader Analysis - retrotruestory/M1DEV GitHub Wiki

Magic-1 Computer Bootloader Analysis

Core Components

Hardware Interfaces

  • UART Communication (Dual Ports)

    • Primary UART (UART0) at 0xFFF0 for console
    • Secondary UART (UART1) at 0xFFE0 for auxiliary
    • Configurable baud rates (1200-38400)
    • Hardware flow control (RTS/CTS)
    • Software flow control (XON/XOFF)
  • IDE/CF Storage Interface

    • Support for Master/Slave IDE devices
    • Compact Flash in True IDE mode
    • 8-bit data transfer mode for CF
    • CHS and LBA addressing modes
    • 512-byte sector operations
  • Real-Time Clock

    • Base address 0xFFD0
    • Time/date registers
    • Interrupt control
    • Hold/busy status monitoring

Memory Management

  • Paging System
    • 22-bit physical address space
    • 2KB page size
    • Page attributes (Present, Writeable, SRAM/Device, Wait states)
    • Split code/data pages (32 each)
    • Device memory mapping in last page

Boot Process

  1. Initial Setup
void setup_address_space() {
    // 1. Set up initial page table mapping
    // 2. Enable paging
    // 3. Copy ROM to SRAM (0x20000-0x27FFF)
    // 4. Remap supervisor space
}
  1. Hardware Initialization
  • UART configuration
  • RTC setup
  • IDE/CF detection and initialization
  • Page table setup
  • Post codes for debug (0x01-0x0A)
  1. Boot Image Management
typedef struct {
    int pid;
    char name[16];
    char free;
    char loaded;
    char default_image;
    char split;
} t_process;

Key Features

  1. Image Management
  • Support for 8 boot images
  • Intel HEX file loading
  • Split/unified code/data spaces
  • PID-based image isolation
  • Default image selection
  1. Storage Operations
  • Sector read/write abstraction
  • Drive identification
  • Error handling and recovery
  • CHS/LBA translation
  1. Security
  • Password protection for critical operations
  • Command access control
  • System state validation

Command Interface

Available Commands

S - Set active drive
P - Show image table
3 - Display drive info
L - Load boot image (Intel hex)
Z - Set default boot image
D - Delete boot image
B - Boot an image
R - Read image table from disk
W - Write boot images to disk
Q - Toggle pre-boot pause

Implementation Details

  1. Boot Image Loading
void read_intel_hex(unsigned int slot) {
    // 1. Parse Intel HEX records
    // 2. Validate checksums
    // 3. Write to appropriate memory space
    // 4. Handle split/unified spaces
}
  1. Image Staging
void stage_boot_image(int slot) {
    // 1. Map transfer pages
    // 2. Copy image to physical memory
    // 3. Set up page tables
    // 4. Handle device page mapping
}
  1. Drive Operations
void read_sector(int sector, char *buf, int drive) {
    // 1. Check drive presence
    // 2. Handle CF vs IDE
    // 3. Calculate CHS if needed
    // 4. Perform transfer
}

Error Handling

  1. Hardware Errors
  • IDE status checking
  • Timeout monitoring
  • Error recovery procedures
  • Diagnostic reporting
  1. Data Validation
  • Checksum verification
  • Address range checking
  • Device presence validation
  • Command parameter validation

System Requirements

  1. Hardware
  • Magic-1 CPU
  • Dual UART ports
  • IDE/CF interface
  • Real-time clock
  • Front panel switches
  1. Memory
  • ROM for initial boot
  • SRAM for execution
  • Device memory space
  1. Storage
  • IDE drive or CF card
  • Formatted with boot sectors
  • Image table structure

This analysis provides the core information needed to implement a compatible bootloader. The code is well-structured with clear separation of hardware abstraction, boot management, and user interface components.

Magic-1 Bootloader Technical Analysis - Part 1: Core Architecture

1. System Architecture Overview

1.1 Memory Layout

  • Physical Address Space: 22-bit (4MB)
  • Page Size: 2KB fixed
  • Memory Map:
0x00000-0x1FFFF: SRAM (128KB)
0x20000-0x2FFFF: ROM Copy Area
0xFFA00-0xFFFF0: Device Space

1.2 Hardware Interface Specifications

UART Controllers

#define UART0_BASE 0xFFF0  // Console
#define UART1_BASE 0xFFE0  // Auxiliary

Register Map:

typedef struct {
    uint8_t DATA;      // 0x0: Data I/O
    uint8_t IER;       // 0x1: Interrupt Enable
    union {
        uint8_t IIR;   // 0x2: Interrupt ID (Read)
        uint8_t FCR;   // 0x2: FIFO Control (Write)
    };
    uint8_t LCR;       // 0x3: Line Control
    uint8_t MCR;       // 0x4: Modem Control
    uint8_t LSR;       // 0x5: Line Status
    uint8_t MSR;       // 0x6: Modem Status
    uint8_t SCRATCH;   // 0x7: Scratch Register
} UART_Registers;

1.3 Boot Process State Machine

stateDiagram-v2
    [*] --> PowerOn
    PowerOn --> InitHardware
    InitHardware --> LoadPageTable
    LoadPageTable --> CopyROM
    CopyROM --> CommandLoop
    CommandLoop --> BootImage
    BootImage --> [*]
Loading

1.4 Core Data Structures

Page Table Entry Format

typedef struct {
    unsigned int present    : 1;    // 0x8000
    unsigned int writeable  : 1;    // 0x4000
    unsigned int sram      : 1;    // 0x2000
    unsigned int wait      : 1;    // 0x1000
    unsigned int address   : 12;   // Physical page number
} PageTableEntry;

Boot Image Table

typedef struct {
    char name[PNAME_SIZE];
    uint8_t split;         // Code/Data split flag
    uint16_t entry_point;
    uint32_t load_addr;
    uint32_t size;
    uint8_t loaded;
    uint8_t default_boot;
} BootImage;

#define NUM_IMAGES 8
typedef BootImage ImageTable[NUM_IMAGES];

1.5 Key Implementation Features

  1. Paging System:
void paging_control(void) {
    /* Page Table Structure:
     * - 64 entries per process
     * - 32 code pages (0x0000-0xFFFF)
     * - 32 data pages (0x0000-0xFFFF)
     * - Last page reserved for devices
     */
    
    // Sample page table initialization
    for(int i = 0; i < 64; i++) {
        if(i < 32) {
            // Code pages
            write_code_pte(i, PAGE_PRESENT | PAGE_SRAM | 
                          (physical_page << 12));
        } else {
            // Data pages
            write_data_pte(i - 32, PAGE_PRESENT | PAGE_WRITEABLE | 
                          PAGE_SRAM | (physical_page << 12));
        }
    }
}
  1. Hardware Initialization Sequence:
void init_hardware(void) {
    // Post code for tracking boot progress
    to_post(0x01);
    
    // Configure UARTs
    init_uart(UART0_BASE, B38400);
    init_uart(UART1_BASE, B9600);
    
    // Reset and detect IDE/CF
    ide_reset();
    
    // Initialize RTC
    rtc_init();
    
    to_post(0x0A);  // Hardware init complete
}

This concludes Part 1 of the analysis, focusing on core architecture.

Magic-1 Bootloader Technical Analysis - Part 2: Boot Process and Image Management

1. Boot Process Implementation

1.1 Initial Boot Sequence

The bootloader initializes in stages defined in bcrt0.s:

_start:
_interrupt_vector:
    sbr     over_ivec
    defw    unhandled_exception   ; IRQ5 (RTC) 
    defw    unhandled_exception   ; IRQ4 (unassigned)
    defw    unhandled_exception   ; IRQ3 (UART0)
    defw    unhandled_exception   ; IRQ2 (UART1)
    defw    unhandled_exception   ; IRQ1 (IDE)
    defw    unhandled_exception   ; IRQ0 (unassigned)

1.2 Memory Management System

The page table management is implemented through these key functions:

typedef struct page_table_entry {
    uint16_t flags;
    uint32_t physical_addr;
} pte_t;

void write_page_table_entry(uint8_t pid, uint8_t page_num, pte_t *entry) {
    uint32_t pte_addr = (pid << 7) | (page_num & 0x3F);
    uint16_t *pt_base = (uint16_t *)0x10000;  // Page table base
    
    pt_base[pte_addr] = entry->flags | 
                        ((entry->physical_addr >> 11) & 0x0FFF);
}

void map_device_page(uint8_t pid) {
    pte_t device_pte = {
        .flags = PAGE_PRESENT | PAGE_DEVICE | PAGE_WAIT,
        .physical_addr = 0xFF000
    };
    write_page_table_entry(pid, 63, &device_pte);
}

1.3 Boot Image Structure

Boot images are managed using a standardized format:

#define IMAGE_HEADER_MAGIC 0x4D31  // "M1"

typedef struct {
    uint16_t magic;          // Magic number for validation
    uint16_t entry_point;    // Code entry point
    uint32_t code_size;      // Size of code segment
    uint32_t data_size;      // Size of data segment
    uint8_t  split;          // Split code/data flag
    uint8_t  reserved[7];    // Padding for alignment
    char     name[16];       // Image name
    uint16_t checksum;       // Header checksum
} boot_image_header_t;

1.4 Storage Interface

The IDE/CF interface implementation:

#define IDE_BASE        0xFFB0
#define IDE_DATA        (IDE_BASE + 0)
#define IDE_ERROR      (IDE_BASE + 1)
#define IDE_SECCOUNT   (IDE_BASE + 2)
#define IDE_SECNUM     (IDE_BASE + 3)
#define IDE_CYLLOW     (IDE_BASE + 4)
#define IDE_CYLHIGH    (IDE_BASE + 5)
#define IDE_DRVHEAD    (IDE_BASE + 6)
#define IDE_STATUS     (IDE_BASE + 7)

int read_sector(uint32_t lba, uint8_t *buffer) {
    // Select drive and wait for ready
    outb(IDE_DRVHEAD, 0xE0 | ((lba >> 24) & 0x0F));
    while(!(inb(IDE_STATUS) & 0x40));  // Wait for DRDY
    
    // Set up LBA registers
    outb(IDE_SECCOUNT, 1);
    outb(IDE_SECNUM, lba & 0xFF);
    outb(IDE_CYLLOW, (lba >> 8) & 0xFF);
    outb(IDE_CYLHIGH, (lba >> 16) & 0xFF);
    
    // Issue READ command
    outb(IDE_STATUS, 0x20);
    
    // Wait for DRQ and transfer data
    while(!(inb(IDE_STATUS) & 0x08));
    for(int i = 0; i < 512; i++) {
        buffer[i] = inb(IDE_DATA);
    }
    
    return (inb(IDE_STATUS) & 0x01) ? -1 : 0;  // Check for error
}

Magic-1 Bootloader Technical Analysis - Part 3: Command Interface

Command Processor Implementation

Main Command Loop Structure

The bootloader implements a command processor that handles user input and executes corresponding functions:

typedef struct command {
    char key;                      // Single character command
    void (*handler)(void);         // Command handler function
    const char *description;       // Help text
    uint8_t requires_password;     // Security flag
} command_t;

static const command_t commands[] = {
    {'S', handle_set_drive,      "Set active drive", 0},
    {'P', handle_show_images,    "Show image table", 0},
    {'L', handle_load_image,     "Load boot image", 1},
    {'B', handle_boot_image,     "Boot an image", 0},
    {'D', handle_delete_image,   "Delete image", 1},
    {0, NULL, NULL, 0}  // Terminator
};

void command_loop(void) {
    char cmd;
    while(1) {
        print_prompt();
        cmd = get_char(CONSOLE);
        
        for(const command_t *cp = commands; cp->key; cp++) {
            if(toupper(cmd) == cp->key) {
                if(cp->requires_password && !verify_password()) {
                    printf("Access denied\n");
                    break;
                }
                cp->handler();
                break;
            }
        }
    }
}

UART Communication Layer

The bootloader uses a robust UART communication layer for user interaction:

typedef struct uart_interface {
    volatile uint8_t *base;
    uint16_t tx_head;
    uint16_t tx_tail;
    uint16_t rx_head;
    uint16_t rx_tail;
    uint8_t tx_buffer[256];
    uint8_t rx_buffer[256];
} uart_t;

static uart_t r_uart0 = { .base = (uint8_t*)UART0_BASE };
static uart_t r_uart1 = { .base = (uint8_t*)UART1_BASE };

int uart_putchar(uart_t *uart, char c) {
    while(!(uart->base[UART_LSR] & UART_XMIT_READY)) {
        // Wait for transmitter
    }
    uart->base[UART_DATA] = c;
    return 0;
}

int uart_getchar(uart_t *uart) {
    while(!(uart->base[UART_LSR] & UART_DATA_READY)) {
        // Wait for receiver
    }
    return uart->base[UART_DATA];
}

Image Loading Implementation

The Intel HEX file parser for loading boot images:

#define MAX_RECORD_SIZE 32

typedef struct {
    uint8_t  length;
    uint16_t address;
    uint8_t  type;
    uint8_t  data[MAX_RECORD_SIZE];
    uint8_t  checksum;
} hex_record_t;

int parse_hex_record(char *line, hex_record_t *record) {
    uint8_t computed_checksum = 0;
    
    if(line[0] != ':') return -1;
    
    // Parse record length
    record->length = hex_to_byte(line + 1);
    computed_checksum += record->length;
    
    // Parse address
    record->address = hex_to_word(line + 3);
    computed_checksum += (record->address >> 8) & 0xFF;
    computed_checksum += record->address & 0xFF;
    
    // Parse record type
    record->type = hex_to_byte(line + 7);
    computed_checksum += record->type;
    
    // Parse data bytes
    for(int i = 0; i < record->length; i++) {
        record->data[i] = hex_to_byte(line + 9 + (i * 2));
        computed_checksum += record->data[i];
    }
    
    // Verify checksum
    record->checksum = hex_to_byte(line + 9 + (record->length * 2));
    computed_checksum = (uint8_t)(-(int8_t)computed_checksum);
    
    return (computed_checksum == record->checksum) ? 0 : -1;
}

Magic-1 Bootloader Technical Analysis - Part 4: Security & Error Handling

Security Implementation

Password Protection System

The bootloader implements a secure password verification system for protected commands:

#define PASSWORD_HASH_SIZE 32
#define SALT_SIZE 16

typedef struct {
    uint8_t hash[PASSWORD_HASH_SIZE];
    uint8_t salt[SALT_SIZE];
} password_store_t;

static password_store_t stored_password;

bool verify_password(void) {
    char password[64];
    uint8_t computed_hash[PASSWORD_HASH_SIZE];
    
    printf("Enter password: ");
    get_string(password, sizeof(password), ECHO_PASSWORD);
    
    compute_hash(password, stored_password.salt, computed_hash);
    return (memcmp(computed_hash, stored_password.hash, 
            PASSWORD_HASH_SIZE) == 0);
}

Error Handling Framework

Error Codes and Management

typedef enum {
    ERR_NONE = 0,
    ERR_HARDWARE = -1,
    ERR_TIMEOUT = -2,
    ERR_CHECKSUM = -3,
    ERR_INVALID_IMAGE = -4,
    ERR_WRITE_PROTECTED = -5
} error_code_t;

typedef struct {
    error_code_t code;
    const char *message;
    uint8_t fatal;
} error_info_t;

static const error_info_t error_table[] = {
    {ERR_NONE, "Success", 0},
    {ERR_HARDWARE, "Hardware failure", 1},
    {ERR_TIMEOUT, "Operation timeout", 0},
    {ERR_CHECKSUM, "Checksum error", 0},
    {ERR_INVALID_IMAGE, "Invalid boot image", 0},
    {ERR_WRITE_PROTECTED, "Write protected", 0}
};

Error Handler Implementation

void handle_error(error_code_t code) {
    for(const error_info_t *ep = error_table; ep->message; ep++) {
        if(ep->code == code) {
            printf("Error: %s\n", ep->message);
            
            // Log error to diagnostic port
            diagnostic_log(ep->message, ep->code);
            
            if(ep->fatal) {
                printf("Fatal error - system halted\n");
                while(1) {
                    // System halt
                    asm volatile("halt");
                }
            }
            return;
        }
    }
}

Hardware Watchdog

#define WATCHDOG_BASE 0xFFC0
#define WATCHDOG_TIMEOUT 1000  // milliseconds

typedef struct {
    volatile uint16_t counter;
    volatile uint16_t control;
} watchdog_t;

static watchdog_t *const watchdog = (watchdog_t*)WATCHDOG_BASE;

void init_watchdog(void) {
    watchdog->control = 0x0001;  // Enable watchdog
    watchdog->counter = WATCHDOG_TIMEOUT;
}

void pet_watchdog(void) {
    watchdog->counter = WATCHDOG_TIMEOUT;
}

void watchdog_isr(void) {
    // Handle watchdog timeout
    handle_error(ERR_TIMEOUT);
}

Diagnostic Output System

#define MAX_LOG_ENTRIES 32

typedef struct {
    uint32_t timestamp;
    error_code_t code;
    char message[64];
} log_entry_t;

static struct {
    log_entry_t entries[MAX_LOG_ENTRIES];
    uint8_t head;
    uint8_t count;
} error_log;

void diagnostic_log(const char *message, error_code_t code) {
    log_entry_t *entry = &error_log.entries[error_log.head];
    
    entry->timestamp = get_rtc_time();
    entry->code = code;
    strncpy(entry->message, message, sizeof(entry->message) - 1);
    
    error_log.head = (error_log.head + 1) % MAX_LOG_ENTRIES;
    if(error_log.count < MAX_LOG_ENTRIES) {
        error_log.count++;
    }
}

Magic-1 Bootloader Technical Analysis - Part 5: Boot Image Loading and Execution

Boot Image Loading System

Boot Image Header Structure

#pragma pack(1)
typedef struct {
    uint16_t magic;           // Magic number 0x4D31 ("M1")
    uint16_t version;         // Format version
    uint32_t load_address;    // Load address for image
    uint32_t entry_point;     // Execution start address
    uint32_t code_size;       // Size of code segment
    uint32_t data_size;       // Size of data segment
    uint8_t  flags;          // Image flags
    char     name[16];       // Image name (null-terminated)
    uint32_t checksum;       // CRC32 of image
} BootImageHeader;
#pragma pack()

Image Loading Process

1. Image Validation

static bool validate_boot_image(const BootImageHeader* header) {
    if (header->magic != MAGIC_SIGNATURE) {
        log_error("Invalid magic number in boot image");
        return false;
    }

    uint32_t computed_crc = crc32(0, (uint8_t*)header + sizeof(header->checksum), 
                                 sizeof(BootImageHeader) - sizeof(header->checksum));
    
    if (computed_crc != header->checksum) {
        log_error("Boot image checksum mismatch");
        return false;
    }

    // Validate memory boundaries
    if (header->load_address + header->code_size + header->data_size > MAX_MEMORY) {
        log_error("Image exceeds memory boundaries");
        return false;
    }

    return true;
}

2. Memory Management for Image Loading

typedef struct {
    uint32_t start_addr;
    uint32_t size;
    bool is_code;
} MemoryRegion;

static bool allocate_image_memory(const BootImageHeader* header, 
                                MemoryRegion* code_region,
                                MemoryRegion* data_region) {
    // Allocate code segment
    code_region->start_addr = header->load_address;
    code_region->size = header->code_size;
    code_region->is_code = true;

    // Set up page tables for code region
    for (uint32_t addr = code_region->start_addr; 
         addr < code_region->start_addr + code_region->size;
         addr += PAGE_SIZE) {
        
        if (!map_page(addr, PAGE_PRESENT | PAGE_EXECUTE)) {
            return false;
        }
    }

    // Similar setup for data region
    data_region->start_addr = code_region->start_addr + code_region->size;
    data_region->size = header->data_size;
    data_region->is_code = false;

    return true;
}

3. Image Transfer and Relocation

typedef struct {
    uint32_t offset;
    uint32_t type;
    uint32_t addend;
} RelocationEntry;

static bool relocate_image(uint8_t* image_base, 
                         const RelocationEntry* relocations,
                         size_t reloc_count) {
    for (size_t i = 0; i < reloc_count; i++) {
        uint32_t* target = (uint32_t*)(image_base + relocations[i].offset);
        
        switch (relocations[i].type) {
            case RELOC_ABSOLUTE:
                *target = relocations[i].addend + (uint32_t)image_base;
                break;
            case RELOC_RELATIVE:
                *target = relocations[i].addend + 
                         (*target - (uint32_t)image_base);
                break;
            default:
                log_error("Unknown relocation type");
                return false;
        }
    }
    return true;
}

4. Boot Image Execution

void execute_boot_image(const BootImageHeader* header) {
    typedef void (*entry_point_t)(void);
    entry_point_t entry = (entry_point_t)header->entry_point;

    // Disable interrupts
    asm volatile("cli");

    // Switch to image's page table
    switch_page_table(header->page_table);

    // Jump to entry point
    entry();

    // Should never return
    log_error("Boot image returned to loader");
    while(1) { }
}

Magic-1 Bootloader Technical Analysis - Part 6: System Initialization and Hardware Setup

Initial System Setup Process

1. Hardware Initialization Sequence

The system initialization is handled by a modular set of functions starting with the primary boot sequence:

    .section .text
    .global _start
    
_start:
    # Initialize stack pointer
    li      sp, 0x8000
    
    # Clear BSS section
    la      a0, __bss_start
    la      a1, __bss_end
    call    clear_bss
    
    # Jump to C initialization
    j       main_init

2. Core Hardware Setup

Memory Controller Configuration

struct MemoryTiming {
    uint8_t refresh_rate;
    uint8_t cas_latency;
    uint8_t ras_timing;
    uint8_t wait_states;
};

static void init_memory_controller(void) {
    volatile uint16_t* const MEM_CTRL = (uint16_t*)0xFF00;
    
    const struct MemoryTiming timing = {
        .refresh_rate = 15,  // 15ms refresh
        .cas_latency = 2,    // CAS Latency 2
        .ras_timing = 3,     // RAS timing
        .wait_states = 1     // 1 wait state
    };
    
    *MEM_CTRL = (timing.refresh_rate << 12) |
                (timing.cas_latency << 8) |
                (timing.ras_timing << 4) |
                timing.wait_states;
}

3. Device Initialization

UART Configuration

typedef struct {
    uint16_t base_addr;
    uint16_t baud_rate;
    uint8_t data_bits;
    uint8_t stop_bits;
    uint8_t parity;
} UartConfig;

static void configure_uart(const UartConfig* config) {
    // Set divisor latch
    uint16_t divisor = UART_CLOCK / (16 * config->baud_rate);
    outb(config->base_addr + LCR, 0x80);  // Enable DLAB
    outb(config->base_addr + DLL, divisor & 0xFF);
    outb(config->base_addr + DLH, (divisor >> 8) & 0xFF);
    
    // Configure line settings
    uint8_t lcr = ((config->data_bits - 5) & 0x3) |
                  ((config->stop_bits - 1) << 2) |
                  (config->parity << 3);
    outb(config->base_addr + LCR, lcr);
    
    // Enable FIFOs
    outb(config->base_addr + FCR, 0x07);
}

4. Interrupt Vector Setup

#define NUM_VECTORS 16

typedef struct {
    uint32_t vector_addr;
    void (*handler)(void);
    uint8_t priority;
} InterruptVector;

static void setup_interrupt_vectors(void) {
    static const InterruptVector vectors[] = {
        { 0x00, nmi_handler,      0 },
        { 0x04, uart0_handler,    2 },
        { 0x08, uart1_handler,    2 },
        { 0x0C, timer_handler,    1 },
        { 0x10, ide_handler,      3 },
        { 0x14, rtc_handler,      4 }
    };
    
    for (int i = 0; i < sizeof(vectors)/sizeof(vectors[0]); i++) {
        // Write vector address and handler
        *(uint32_t*)vectors[i].vector_addr = (uint32_t)vectors[i].handler;
        
        // Set interrupt priority
        set_interrupt_priority(i, vectors[i].priority);
    }
}

5. System Clock Configuration

#define CLOCK_BASE 0xFF20
#define PLL_CTRL  (CLOCK_BASE + 0)
#define CLK_DIV   (CLOCK_BASE + 2)

struct ClockConfig {
    uint8_t pll_mult;     // PLL multiplier (2-16)
    uint8_t pll_div;      // PLL divider (1-8)
    uint8_t sys_div;      // System clock divider
    uint8_t periph_div;   // Peripheral clock divider
};

static void configure_system_clocks(const struct ClockConfig* config) {
    // Configure PLL
    uint16_t pll_ctrl = (config->pll_mult << 8) | config->pll_div;
    outw(PLL_CTRL, pll_ctrl);
    
    // Wait for PLL lock
    while (!(inw(PLL_CTRL) & 0x8000)) {
        continue;
    }
    
    // Set clock dividers
    uint16_t div_ctrl = (config->sys_div << 8) | config->periph_div;
    outw(CLK_DIV, div_ctrl);
}

Magic-1 Bootloader Technical Analysis - Part 7: IDE/CF Storage Management

IDE/CF Controller Implementation

Base Configuration Structure

#define IDE_BASE       0xFFB0
#define IDE_DATA       (IDE_BASE + 0)
#define IDE_ERROR      (IDE_BASE + 1)
#define IDE_FEATURES   (IDE_BASE + 1)
#define IDE_SECCOUNT   (IDE_BASE + 2)
#define IDE_SECTOR     (IDE_BASE + 3)
#define IDE_CYLLOW     (IDE_BASE + 4)
#define IDE_CYLHIGH    (IDE_BASE + 5)
#define IDE_DRVHEAD    (IDE_BASE + 6)
#define IDE_STATUS     (IDE_BASE + 7)
#define IDE_COMMAND    (IDE_BASE + 7)

typedef struct {
    uint8_t  present;       // Device presence flag
    uint8_t  is_cf;        // CompactFlash flag
    uint16_t cylinders;    // Number of cylinders
    uint8_t  heads;        // Number of heads
    uint8_t  sectors;      // Sectors per track
    uint32_t capacity;     // Total capacity in sectors
} ide_device_t;

Device Detection and Initialization

static ide_device_t devices[2] = {0}; // Master and Slave

static int identify_device(uint8_t device) {
    uint16_t buffer[256];
    uint8_t status, cl, ch;
    
    // Select device
    outb(IDE_DRVHEAD, device ? 0xB0 : 0xA0);
    delay_ms(1);
    
    // Check for CompactFlash signature
    cl = inb(IDE_CYLLOW);
    ch = inb(IDE_CYLHIGH);
    
    if (cl == 0x14 && ch == 0xEB) {
        devices[device].is_cf = 1;
    }
    
    // Issue IDENTIFY command
    outb(IDE_COMMAND, 0xEC);
    status = inb(IDE_STATUS);
    
    if (status == 0) {
        return -1; // Device not present
    }
    
    // Wait for data ready
    while (((status = inb(IDE_STATUS)) & 0x80) != 0);
    
    // Read identification space
    for (int i = 0; i < 256; i++) {
        buffer[i] = inw(IDE_DATA);
    }
    
    // Parse identification data
    devices[device].present = 1;
    devices[device].cylinders = buffer[1];
    devices[device].heads = buffer[3];
    devices[device].sectors = buffer[6];
    devices[device].capacity = buffer[60] | (buffer[61] << 16);
    
    return 0;
}

Sector Read/Write Implementation

#define SECTOR_SIZE 512

typedef enum {
    TRANSFER_READ,
    TRANSFER_WRITE
} transfer_mode_t;

static int transfer_sectors(uint8_t device, uint32_t lba, 
                          uint8_t count, void* buffer,
                          transfer_mode_t mode) {
    uint8_t cmd = (mode == TRANSFER_READ) ? 0x20 : 0x30;
    
    // Select device and write parameters
    outb(IDE_DRVHEAD, (device ? 0xF0 : 0xE0) | ((lba >> 24) & 0x0F));
    outb(IDE_SECCOUNT, count);
    outb(IDE_SECTOR, lba & 0xFF);
    outb(IDE_CYLLOW, (lba >> 8) & 0xFF);
    outb(IDE_CYLHIGH, (lba >> 16) & 0xFF);
    
    // Issue command
    outb(IDE_COMMAND, cmd);
    
    for (int i = 0; i < count; i++) {
        // Wait for DRQ
        while ((inb(IDE_STATUS) & 0x08) == 0) {
            if (inb(IDE_STATUS) & 0x01) {
                return -1; // Error
            }
        }
        
        // Transfer data
        if (mode == TRANSFER_READ) {
            for (int j = 0; j < SECTOR_SIZE/2; j++) {
                ((uint16_t*)buffer)[j] = inw(IDE_DATA);
            }
        } else {
            for (int j = 0; j < SECTOR_SIZE/2; j++) {
                outw(IDE_DATA, ((uint16_t*)buffer)[j]);
            }
        }
        
        buffer = (uint8_t*)buffer + SECTOR_SIZE;
    }
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 8: Memory Management System

Memory Management Unit Implementation

Page Table Structure

The Magic-1 uses a two-level page table system with separate code and data spaces.

#define PAGE_SIZE           2048    // 2KB pages
#define PAGE_TABLE_ENTRIES  64      // 32 code + 32 data pages
#define PAGE_PRESENT       0x8000
#define PAGE_WRITEABLE    0x4000
#define PAGE_SRAM         0x2000
#define PAGE_WAIT         0x1000

typedef struct {
    uint16_t entries[PAGE_TABLE_ENTRIES];
} PageTable;

typedef struct {
    uint16_t ptb;          // Page Table Base
    PageTable *table;      // Pointer to page table
    uint8_t pid;          // Process ID (0-7)
} MMUContext;

MMU Core Functions

Here's the core MMU implementation:

static MMUContext current_context;

static uint32_t translate_address(uint16_t virtual_addr, bool is_code) {
    uint8_t page_index = (virtual_addr >> 11) & 0x1F;
    uint16_t offset = virtual_addr & 0x7FF;
    
    // Add 32 to page_index for data pages
    if (!is_code) {
        page_index += 32;
    }
    
    uint16_t pte = current_context.table->entries[page_index];
    
    if (!(pte & PAGE_PRESENT)) {
        handle_page_fault(virtual_addr);
        return 0xFFFFFFFF;
    }
    
    uint32_t physical_page = pte & 0x0FFF;
    return (physical_page << 11) | offset;
}

void mmu_switch_context(uint8_t pid) {
    current_context.pid = pid;
    current_context.ptb = pid << 7;  // PTB = PID * 128
    current_context.table = (PageTable*)(0x10000 + current_context.ptb);
    
    // Update hardware PTB register
    outw(MMU_PTB_REG, current_context.ptb);
}

int mmu_map_page(uint8_t page_num, uint32_t physical_addr, uint16_t flags) {
    if (page_num >= PAGE_TABLE_ENTRIES) {
        return -1;
    }
    
    uint16_t pte = (physical_addr >> 11) & 0x0FFF;
    pte |= flags & 0xF000;
    
    current_context.table->entries[page_num] = pte;
    return 0;
}

Page Fault Handler

void handle_page_fault(uint16_t fault_addr) {
    uint8_t fault_page = (fault_addr >> 11) & 0x3F;
    bool is_code = fault_page < 32;
    
    // Log the fault
    printf("Page fault: addr=0x%04X page=%d %s\n",
           fault_addr, fault_page, is_code ? "code" : "data");
           
    if (is_code) {
        // Handle code page fault
        load_code_page(fault_page);
    } else {
        // Handle data page fault
        allocate_data_page(fault_page - 32);
    }
}

static void load_code_page(uint8_t page_num) {
    // Allocate physical page
    uint32_t phys_addr = allocate_physical_page();
    
    // Load page contents from boot image
    load_page_from_image(page_num, (void*)phys_addr);
    
    // Map the page
    mmu_map_page(page_num, phys_addr, 
                 PAGE_PRESENT | PAGE_SRAM);
}

Magic-1 Bootloader Technical Analysis - Part 9: Boot Image Format and Loading

Boot Image Format Specification

Header Structure

The boot image begins with a header that defines the image characteristics and loading requirements:

#pragma pack(push, 1)
typedef struct {
    uint16_t magic;           /* 'M1' (0x4D31) */
    uint8_t  version;        /* Format version (current: 1) */
    uint8_t  flags;          /* Image flags */
    uint32_t load_address;   /* Base load address */
    uint32_t entry_point;    /* Execution entry point */
    uint32_t code_size;      /* Size of code segment */
    uint32_t data_size;      /* Size of data segment */
    uint32_t bss_size;       /* Size of BSS segment */
    char     name[16];       /* Image name (null-terminated) */
    uint32_t checksum;       /* CRC-32 of image content */
} BootImageHeader;
#pragma pack(pop)

Image Loader Implementation

Here's the core image loading functionality:

#include "boot_image.h"
#include "mmu.h"
#include "crc32.h"

#define MAX_IMAGE_SIZE (512 * 1024)  /* 512KB maximum image size */

static uint8_t image_buffer[MAX_IMAGE_SIZE];

int load_boot_image(const char* image_name) {
    BootImageHeader* header = (BootImageHeader*)image_buffer;
    int status;
    
    /* Read image from storage */
    status = read_image_from_storage(image_name, image_buffer, MAX_IMAGE_SIZE);
    if (status < 0) {
        return status;
    }
    
    /* Validate header */
    if (header->magic != 0x4D31) {
        return -1;  /* Invalid magic number */
    }
    
    /* Verify checksum */
    uint32_t computed_crc = crc32(0, 
        image_buffer + sizeof(BootImageHeader), 
        header->code_size + header->data_size);
        
    if (computed_crc != header->checksum) {
        return -2;  /* Checksum mismatch */
    }
    
    /* Map memory regions */
    status = map_image_memory(header);
    if (status < 0) {
        return status;
    }
    
    /* Copy segments to memory */
    copy_segments(header);
    
    return 0;
}

Memory Mapping Handler

static int map_image_memory(const BootImageHeader* header) {
    uint32_t code_pages = (header->code_size + PAGE_SIZE - 1) / PAGE_SIZE;
    uint32_t data_pages = (header->data_size + PAGE_SIZE - 1) / PAGE_SIZE;
    uint32_t bss_pages = (header->bss_size + PAGE_SIZE - 1) / PAGE_SIZE;
    
    /* Map code pages */
    for (uint32_t i = 0; i < code_pages; i++) {
        uint32_t phys_addr = allocate_physical_page();
        if (phys_addr == 0xFFFFFFFF) {
            return -1;  /* Out of memory */
        }
        
        mmu_map_page(i, phys_addr, 
            PAGE_PRESENT | PAGE_SRAM | PAGE_WAIT);
    }
    
    /* Map data and BSS pages */
    for (uint32_t i = 0; i < data_pages + bss_pages; i++) {
        uint32_t phys_addr = allocate_physical_page();
        if (phys_addr == 0xFFFFFFFF) {
            return -1;
        }
        
        mmu_map_page(32 + i, phys_addr, 
            PAGE_PRESENT | PAGE_SRAM | PAGE_WRITEABLE | PAGE_WAIT);
    }
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 10: Debugging and System Monitoring

Debug Support Framework

Debug Console Implementation

#define DEBUG_UART_BASE 0xFFE0
#define DEBUG_BUFFER_SIZE 256

typedef struct {
    char buffer[DEBUG_BUFFER_SIZE];
    uint16_t head;
    uint16_t tail;
    uint8_t echo_enabled;
} DebugConsole;

System Monitor Core

#include "debug_console.h"

static const struct {
    const char* cmd;
    void (*handler)(int argc, char* argv[]);
    const char* help;
} debug_commands[] = {
    {"dump",    cmd_memory_dump,    "Display memory contents"},
    {"regs",    cmd_show_regs,     "Show CPU registers"},
    {"mmu",     cmd_show_mmu,      "Display MMU status"},
    {"trace",   cmd_set_trace,     "Set instruction trace"},
    {"break",   cmd_breakpoint,    "Set/clear breakpoint"},
    {"step",    cmd_single_step,   "Single step execution"},
    {NULL, NULL, NULL}
};

struct DebugState {
    uint32_t breakpoints[4];
    uint8_t bp_count;
    uint8_t trace_enabled;
    uint8_t single_step;
    uint16_t last_pc;
} debug_state;

Memory and Register Display

void cmd_memory_dump(int argc, char* argv[]) {
    uint32_t addr = parse_hex_arg(argv[1]);
    uint16_t count = (argc > 2) ? parse_hex_arg(argv[2]) : 16;
    
    for (uint16_t i = 0; i < count; i += 16) {
        printf("%04X: ", addr + i);
        
        // Display hex values
        for (int j = 0; j < 16; j++) {
            printf("%02X ", read_memory_byte(addr + i + j));
            if (j == 7) printf("- ");
        }
        
        // Display ASCII representation
        printf("  |");
        for (int j = 0; j < 16; j++) {
            uint8_t byte = read_memory_byte(addr + i + j);
            printf("%c", (byte >= 32 && byte <= 126) ? byte : '.');
        }
        printf("|\n");
    }
}

Instruction Trace Implementation

void trace_instruction(uint16_t pc, uint16_t opcode) {
    static char disasm_buffer[64];
    
    if (!debug_state.trace_enabled) {
        return;
    }
    
    // Disassemble instruction
    disassemble_instruction(pc, opcode, disasm_buffer);
    
    // Display registers alongside instruction
    printf("%04X: %-32s  A=%04X B=%04X C=%04X SP=%04X\n",
           pc, disasm_buffer,
           get_register(REG_A),
           get_register(REG_B),
           get_register(REG_C),
           get_register(REG_SP));
}

Breakpoint Management

int set_breakpoint(uint16_t addr) {
    if (debug_state.bp_count >= 4) {
        printf("Error: Maximum breakpoints reached\n");
        return -1;
    }
    
    // Save original instruction
    uint16_t original = read_memory_word(addr);
    
    // Insert breakpoint instruction (TRAP)
    write_memory_word(addr, 0xFFFF);
    
    // Store breakpoint info
    debug_state.breakpoints[debug_state.bp_count++] = 
        (addr << 16) | original;
        
    printf("Breakpoint set at %04X\n", addr);
    return 0;
}

The debug framework provides essential tools for development and troubleshooting of the Magic-1 bootloader.

Magic-1 Bootloader Technical Analysis - Part 11: Error Handling and Recovery

Error Management System

Error Code Definitions

#define ERR_SUCCESS          0x00
#define ERR_HARDWARE        0x01
#define ERR_MEMORY          0x02
#define ERR_TIMEOUT         0x03
#define ERR_CHECKSUM        0x04
#define ERR_INVALID_IMAGE   0x05
#define ERR_IO              0x06
#define ERR_MMU             0x07
#define ERR_PROTECTION      0x08

typedef struct error_info {
    uint8_t code;
    const char* message;
    uint8_t severity;
    uint8_t recoverable;
} error_info_t;

static const error_info_t error_table[] = {
    {ERR_SUCCESS,      "Operation successful",        0, 1},
    {ERR_HARDWARE,     "Hardware failure",           3, 0},
    {ERR_MEMORY,       "Memory allocation failed",   2, 1},
    {ERR_TIMEOUT,      "Operation timeout",          1, 1},
    {ERR_CHECKSUM,     "Checksum verification failed", 2, 1},
    {ERR_INVALID_IMAGE,"Invalid boot image format",  2, 1},
    {ERR_IO,          "I/O error",                  2, 1},
    {ERR_MMU,         "MMU configuration error",    3, 0},
    {ERR_PROTECTION,  "Protection violation",       3, 0},
    {0, NULL, 0, 0}
};

Error Handler Implementation

#include "errors.h"

#define MAX_ERROR_STACK 16
#define ERROR_LOG_SIZE  32

typedef struct {
    uint32_t timestamp;
    uint8_t error_code;
    uint16_t pc;
    uint8_t context;
} error_record_t;

static struct {
    error_record_t log[ERROR_LOG_SIZE];
    uint8_t log_head;
    uint8_t log_count;
    uint8_t error_stack[MAX_ERROR_STACK];
    uint8_t stack_ptr;
} error_context;

void handle_error(uint8_t error_code) {
    const error_info_t *info = NULL;
    
    // Find error info
    for(const error_info_t *ep = error_table; ep->message; ep++) {
        if(ep->code == error_code) {
            info = ep;
            break;
        }
    }
    
    if(!info) {
        printf("Unknown error code: 0x%02X\n", error_code);
        return;
    }
    
    // Log the error
    error_record_t *record = &error_context.log[error_context.log_head];
    record->timestamp = get_system_time();
    record->error_code = error_code;
    record->pc = get_current_pc();
    record->context = get_current_context();
    
    error_context.log_head = (error_context.log_head + 1) % ERROR_LOG_SIZE;
    if(error_context.log_count < ERROR_LOG_SIZE)
        error_context.log_count++;
    
    // Push to error stack
    if(error_context.stack_ptr < MAX_ERROR_STACK)
        error_context.error_stack[error_context.stack_ptr++] = error_code;
    
    // Handle based on severity
    switch(info->severity) {
        case 3: // Fatal
            printf("FATAL ERROR: %s\n", info->message);
            system_halt();
            break;
        case 2: // Severe
            printf("ERROR: %s\n", info->message);
            if(!info->recoverable)
                system_restart();
            break;
        case 1: // Warning
            printf("Warning: %s\n", info->message);
            break;
        default:
            break;
    }
}

Magic-1 Bootloader Technical Analysis - Part 12: System Configuration and Hardware Detection

System Configuration Manager

Configuration Structure

Creates a centralized system for managing hardware settings and boot parameters.

#pragma once

#include <stdint.h>

typedef struct {
    struct {
        uint16_t base_memory;      // Base memory size in KB
        uint16_t extended_memory;   // Extended memory size in KB
        uint8_t  num_ide_drives;   // Number of IDE drives detected
        uint8_t  cf_card_present;  // CompactFlash card status
        uint8_t  uart_ports;       // Bitmap of available UART ports
    } hardware;
    
    struct {
        uint32_t load_address;     // Boot image load address
        uint8_t  auto_boot;        // Auto-boot flag
        uint8_t  boot_delay;       // Boot delay in seconds
        char     default_image[16];// Default boot image name
    } boot;
    
    struct {
        uint8_t  debug_level;      // Debug output level
        uint16_t console_baud;     // Console UART baud rate
        uint8_t  memory_wait;      // Memory wait states
        uint8_t  ide_mode;         // IDE interface mode
    } settings;
} SystemConfig;

extern SystemConfig system_config;

Hardware Detection Implementation

#include "system_config.h"

#define MEMORY_TEST_PATTERN 0x55AA
#define MAX_MEMORY_SIZE    0x20000  // 128KB

static int detect_memory_size(void) {
    uint16_t *mem_ptr = (uint16_t *)0;
    uint16_t size = 0;
    
    for(; size < MAX_MEMORY_SIZE; size += 1024) {
        mem_ptr[size/2] = MEMORY_TEST_PATTERN;
        if(mem_ptr[size/2] != MEMORY_TEST_PATTERN) {
            break;
        }
    }
    
    return size;
}

static void detect_uart_ports(void) {
    static const uint16_t uart_bases[] = {0xFFF0, 0xFFE0};
    uint8_t ports = 0;
    
    for(int i = 0; i < 2; i++) {
        // Write to scratch register
        outb(uart_bases[i] + 7, 0x55);
        if(inb(uart_bases[i] + 7) == 0x55) {
            ports |= (1 << i);
        }
    }
    
    system_config.hardware.uart_ports = ports;
}

int initialize_system_config(void) {
    // Clear configuration structure
    memset(&system_config, 0, sizeof(SystemConfig));
    
    // Detect memory size
    system_config.hardware.base_memory = detect_memory_size();
    
    // Detect UART ports
    detect_uart_ports();
    
    // Detect IDE/CF devices
    system_config.hardware.num_ide_drives = detect_ide_devices();
    system_config.hardware.cf_card_present = detect_cf_card();
    
    // Set default settings
    system_config.settings.console_baud = 9600;
    system_config.settings.debug_level = 1;
    system_config.settings.memory_wait = 1;
    
    return 0;
}

Configuration Storage

#define CONFIG_SECTOR_ADDR 0x1F000
#define CONFIG_MAGIC      0x4D31  // "M1"

typedef struct {
    uint16_t magic;
    uint16_t version;
    uint16_t checksum;
    SystemConfig config;
} ConfigBlock;

int save_system_config(void) {
    ConfigBlock block;
    
    block.magic = CONFIG_MAGIC;
    block.version = 1;
    memcpy(&block.config, &system_config, sizeof(SystemConfig));
    
    // Calculate checksum
    block.checksum = calculate_checksum(&block.config, sizeof(SystemConfig));
    
    // Write to storage
    return write_sector(CONFIG_SECTOR_ADDR, &block, sizeof(ConfigBlock));
}

int load_system_config(void) {
    ConfigBlock block;
    
    if(read_sector(CONFIG_SECTOR_ADDR, &block, sizeof(ConfigBlock)) != 0) {
        return -1;
    }
    
    if(block.magic != CONFIG_MAGIC || 
       block.checksum != calculate_checksum(&block.config, sizeof(SystemConfig))) {
        return -1;
    }
    
    memcpy(&system_config, &block.config, sizeof(SystemConfig));
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 13: Device Driver Framework

Core Driver Architecture

Driver Registration System

Implements a modular driver system for hardware devices.

#pragma once

typedef enum {
    DEVICE_UART,
    DEVICE_IDE,
    DEVICE_RTC,
    DEVICE_CF,
    DEVICE_MAX
} device_type_t;

typedef struct device_ops {
    int  (*init)(void *config);
    int  (*read)(void *buf, size_t count);
    int  (*write)(const void *buf, size_t count);
    int  (*ioctl)(int cmd, void *arg);
    void (*shutdown)(void);
} device_ops_t;

typedef struct device_driver {
    const char *name;
    device_type_t type;
    device_ops_t ops;
    void *private_data;
    uint8_t initialized;
} device_driver_t;

Driver Manager Implementation

#include "driver_core.h"

#define MAX_DRIVERS 8

static struct {
    device_driver_t *drivers[MAX_DRIVERS];
    uint8_t driver_count;
} driver_manager;

int register_driver(device_driver_t *driver) {
    if (driver_manager.driver_count >= MAX_DRIVERS) {
        return -1;
    }
    
    driver_manager.drivers[driver_manager.driver_count++] = driver;
    return 0;
}

device_driver_t *get_driver(device_type_t type) {
    for (int i = 0; i < driver_manager.driver_count; i++) {
        if (driver_manager.drivers[i]->type == type) {
            return driver_manager.drivers[i];
        }
    }
    return NULL;
}

UART Driver Example

#include "driver_core.h"

#define UART_RX_BUFFER_SIZE 256
#define UART_TX_BUFFER_SIZE 256

typedef struct {
    uint16_t base_addr;
    uint8_t rx_buffer[UART_RX_BUFFER_SIZE];
    uint8_t tx_buffer[UART_TX_BUFFER_SIZE];
    uint16_t rx_head, rx_tail;
    uint16_t tx_head, tx_tail;
} uart_private_t;

static int uart_init(void *config) {
    uart_private_t *priv = (uart_private_t *)config;
    
    // Initialize UART hardware
    outb(priv->base_addr + 3, 0x80);    // Enable DLAB
    outb(priv->base_addr + 0, 0x0C);    // Set baud rate divisor
    outb(priv->base_addr + 1, 0x00);
    outb(priv->base_addr + 3, 0x03);    // 8N1
    outb(priv->base_addr + 2, 0x07);    // Enable FIFOs
    
    return 0;
}

static device_driver_t uart_driver = {
    .name = "UART",
    .type = DEVICE_UART,
    .ops = {
        .init = uart_init,
        .read = uart_read,
        .write = uart_write,
        .ioctl = uart_ioctl,
        .shutdown = uart_shutdown
    }
};

This implements the core device driver framework for the Magic-1 bootloader.

Magic-1 Bootloader Technical Analysis - Part 14: Timer and Interrupt Management

Timer and Interrupt System

Interrupt Vector Table

The Magic-1 system uses a table-driven interrupt management system.

#define NUM_INTERRUPTS    8
#define VECTOR_TABLE_BASE 0x0000

typedef struct {
    void (*handler)(void);
    uint8_t priority;
    uint8_t enabled;
    uint32_t count;
    const char* name;
} interrupt_vector_t;

static interrupt_vector_t interrupt_vectors[NUM_INTERRUPTS] = {
    { nmi_handler,     0, 1, 0, "NMI"     },
    { timer_handler,   1, 1, 0, "Timer"   },
    { uart0_handler,   2, 1, 0, "UART0"   },
    { uart1_handler,   2, 1, 0, "UART1"   },
    { ide_handler,     3, 1, 0, "IDE"     },
    { rtc_handler,     4, 1, 0, "RTC"     },
    { fault_handler,   0, 1, 0, "Fault"   },
    { trap_handler,    0, 1, 0, "Trap"    }
};

Timer Implementation

#define TIMER_BASE      0xFFD0
#define TIMER_COUNT     (TIMER_BASE + 0)
#define TIMER_CONTROL   (TIMER_BASE + 2)
#define TIMER_STATUS    (TIMER_BASE + 4)

#define TIMER_ENABLE    0x01
#define TIMER_INTERRUPT 0x02
#define TIMER_RELOAD    0x04

typedef struct {
    uint16_t reload_value;
    uint32_t tick_count;
    void (*callback)(void);
} timer_context_t;

static timer_context_t timer_ctx;

void init_timer(uint16_t reload_value, void (*callback)(void)) {
    timer_ctx.reload_value = reload_value;
    timer_ctx.callback = callback;
    timer_ctx.tick_count = 0;
    
    // Configure timer hardware
    outw(TIMER_COUNT, reload_value);
    outw(TIMER_CONTROL, TIMER_ENABLE | TIMER_INTERRUPT | TIMER_RELOAD);
}

void timer_handler(void) {
    timer_ctx.tick_count++;
    
    // Clear interrupt
    outb(TIMER_STATUS, 0);
    
    if (timer_ctx.callback) {
        timer_ctx.callback();
    }
}

Interrupt Controller

#define INT_CTRL_BASE   0xFFC0
#define INT_MASK        (INT_CTRL_BASE + 0)
#define INT_STATUS      (INT_CTRL_BASE + 2)
#define INT_ACK         (INT_CTRL_BASE + 4)

void enable_interrupt(uint8_t irq) {
    uint16_t mask = inw(INT_MASK);
    mask |= (1 << irq);
    outw(INT_MASK, mask);
}

void disable_interrupt(uint8_t irq) {
    uint16_t mask = inw(INT_MASK);
    mask &= ~(1 << irq);
    outw(INT_MASK, mask);
}

void acknowledge_interrupt(uint8_t irq) {
    outw(INT_ACK, 1 << irq);
}

// Main interrupt dispatcher
void interrupt_dispatch(void) {
    uint16_t status = inw(INT_STATUS);
    
    for (int i = 0; i < NUM_INTERRUPTS; i++) {
        if (status & (1 << i)) {
            if (interrupt_vectors[i].enabled && interrupt_vectors[i].handler) {
                interrupt_vectors[i].count++;
                interrupt_vectors[i].handler();
            }
            acknowledge_interrupt(i);
        }
    }
}

Magic-1 Bootloader Technical Analysis - Part 15: Boot Process and Image Loading

Primary Boot Sequence

Boot State Machine

Implements the main boot sequence controller:

typedef enum {
    BOOT_STATE_INIT,
    BOOT_STATE_HARDWARE_DETECT,
    BOOT_STATE_MEMORY_TEST,
    BOOT_STATE_LOAD_CONFIG,
    BOOT_STATE_MOUNT_STORAGE,
    BOOT_STATE_LOAD_IMAGE,
    BOOT_STATE_EXECUTE
} boot_state_t;

typedef struct {
    boot_state_t current_state;
    uint8_t retry_count;
    uint32_t start_time;
    char error_message[64];
} boot_context_t;

Boot Sequence Implementation

#include "boot_manager.h"
#include "hardware_detect.h"
#include "memory_test.h"
#include "storage.h"

static boot_context_t boot_ctx;

int execute_boot_sequence(void) {
    int status = 0;
    
    // Initialize boot context
    boot_ctx.current_state = BOOT_STATE_INIT;
    boot_ctx.retry_count = 0;
    boot_ctx.start_time = get_rtc_time();
    
    while (boot_ctx.current_state != BOOT_STATE_EXECUTE) {
        switch (boot_ctx.current_state) {
            case BOOT_STATE_INIT:
                status = initialize_core_hardware();
                if (status == 0) {
                    boot_ctx.current_state = BOOT_STATE_HARDWARE_DETECT;
                }
                break;
                
            case BOOT_STATE_HARDWARE_DETECT:
                status = detect_hardware_configuration();
                if (status == 0) {
                    boot_ctx.current_state = BOOT_STATE_MEMORY_TEST;
                }
                break;
                
            case BOOT_STATE_MEMORY_TEST:
                status = perform_memory_test();
                if (status == 0) {
                    boot_ctx.current_state = BOOT_STATE_LOAD_CONFIG;
                }
                break;
                
            case BOOT_STATE_LOAD_CONFIG:
                status = load_system_configuration();
                if (status == 0) {
                    boot_ctx.current_state = BOOT_STATE_MOUNT_STORAGE;
                }
                break;
                
            case BOOT_STATE_MOUNT_STORAGE:
                status = mount_boot_storage();
                if (status == 0) {
                    boot_ctx.current_state = BOOT_STATE_LOAD_IMAGE;
                }
                break;
                
            case BOOT_STATE_LOAD_IMAGE:
                status = load_boot_image();
                if (status == 0) {
                    boot_ctx.current_state = BOOT_STATE_EXECUTE;
                }
                break;
                
            default:
                sprintf(boot_ctx.error_message, "Invalid boot state: %d", 
                        boot_ctx.current_state);
                return -1;
        }
        
        if (status != 0) {
            handle_boot_error(status);
            if (++boot_ctx.retry_count >= MAX_BOOT_RETRIES) {
                return -1;
            }
        }
    }
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 16: Storage System Implementation

Storage Subsystem Architecture

Core Storage Interface

The storage system provides a unified interface for different storage devices:

#define SECTOR_SIZE     512
#define MAX_DEVICES     4
#define MAX_PARTITIONS  16

typedef enum {
    STORAGE_IDE,
    STORAGE_CF,
    STORAGE_ROM
} storage_type_t;

typedef struct {
    uint32_t start_sector;
    uint32_t num_sectors;
    uint8_t  type;
    uint8_t  bootable;
} partition_entry_t;

typedef struct storage_device {
    storage_type_t type;
    uint8_t  id;
    uint32_t sector_count;
    uint16_t sector_size;
    
    // Device operations
    int (*read_sector)(struct storage_device *dev, uint32_t sector, void *buffer);
    int (*write_sector)(struct storage_device *dev, uint32_t sector, const void *buffer);
    int (*ioctl)(struct storage_device *dev, int cmd, void *arg);
    
    // Partition table
    partition_entry_t partitions[MAX_PARTITIONS];
    uint8_t partition_count;
    
    // Device-specific data
    void *private_data;
} storage_device_t;

Storage Manager Implementation

#include "storage.h"

static struct {
    storage_device_t *devices[MAX_DEVICES];
    uint8_t device_count;
    storage_device_t *boot_device;
} storage_manager;

int register_storage_device(storage_device_t *device) {
    if (storage_manager.device_count >= MAX_DEVICES) {
        return -1;
    }
    
    // Initialize device
    if (scan_partitions(device) != 0) {
        return -2;
    }
    
    storage_manager.devices[storage_manager.device_count++] = device;
    
    // Set as boot device if bootable partition found
    for (int i = 0; i < device->partition_count; i++) {
        if (device->partitions[i].bootable) {
            storage_manager.boot_device = device;
            break;
        }
    }
    
    return 0;
}

int read_storage_sectors(storage_device_t *dev, 
                        uint32_t start_sector,
                        uint32_t count,
                        void *buffer) {
    if (!dev || !dev->read_sector) {
        return -1;
    }
    
    uint8_t *buf = (uint8_t *)buffer;
    for (uint32_t i = 0; i < count; i++) {
        int status = dev->read_sector(dev, start_sector + i, 
                                    buf + (i * dev->sector_size));
        if (status != 0) {
            return status;
        }
    }
    
    return 0;
}

Partition Table Scanner

#define MBR_SIGNATURE   0xAA55
#define PARTITION_ENTRY_OFFSET 0x1BE

typedef struct {
    uint8_t  boot_flag;
    uint8_t  start_head;
    uint16_t start_sector_cyl;
    uint8_t  type;
    uint8_t  end_head;
    uint16_t end_sector_cyl;
    uint32_t start_sector;
    uint32_t num_sectors;
} __attribute__((packed)) mbr_partition_t;

int scan_partitions(storage_device_t *dev) {
    uint8_t mbr[SECTOR_SIZE];
    mbr_partition_t *part;
    
    // Read MBR
    if (dev->read_sector(dev, 0, mbr) != 0) {
        return -1;
    }
    
    // Verify MBR signature
    if (*(uint16_t *)&mbr[510] != MBR_SIGNATURE) {
        return -2;
    }
    
    // Parse partition entries
    dev->partition_count = 0;
    part = (mbr_partition_t *)&mbr[PARTITION_ENTRY_OFFSET];
    
    for (int i = 0; i < 4; i++, part++) {
        if (part->type == 0) {
            continue;
        }
        
        dev->partitions[dev->partition_count].start_sector = part->start_sector;
        dev->partitions[dev->partition_count].num_sectors = part->num_sectors;
        dev->partitions[dev->partition_count].type = part->type;
        dev->partitions[dev->partition_count].bootable = 
            (part->boot_flag == 0x80);
            
        dev->partition_count++;
    }
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 17: Console Interface and Command Processing

Console Command System

The console interface provides interactive control over the bootloader operations.

Command Handler Structure

typedef struct command_handler {
    const char* command;        // Command string
    const char* description;    // Help text
    uint8_t min_args;          // Minimum arguments required
    uint8_t max_args;          // Maximum arguments allowed
    int (*handler)(int argc, char* argv[]);  // Command function
    uint8_t requires_auth;     // Whether authentication is required
} command_handler_t;

#define MAX_COMMAND_LENGTH 32
#define MAX_ARGS 8
#define COMMAND_BUFFER_SIZE 256

Command Processor Implementation

static const command_handler_t command_table[] = {
    {
        .command = "boot",
        .description = "Boot specified image",
        .min_args = 1,
        .max_args = 2,
        .handler = cmd_boot_image,
        .requires_auth = 1
    },
    {
        .command = "list",
        .description = "List available boot images",
        .min_args = 0,
        .max_args = 0,
        .handler = cmd_list_images,
        .requires_auth = 0
    },
    {
        .command = "set",
        .description = "Set configuration parameter",
        .min_args = 2,
        .max_args = 2,
        .handler = cmd_set_config,
        .requires_auth = 1
    },
    {
        .command = "help",
        .description = "Show available commands",
        .min_args = 0,
        .max_args = 1,
        .handler = cmd_show_help,
        .requires_auth = 0
    },
    { NULL, NULL, 0, 0, NULL, 0 }  // Terminator
};

int process_command(const char* input) {
    char buffer[COMMAND_BUFFER_SIZE];
    char* argv[MAX_ARGS];
    int argc = 0;
    
    // Copy input to avoid modifying original
    strncpy(buffer, input, COMMAND_BUFFER_SIZE);
    buffer[COMMAND_BUFFER_SIZE - 1] = '\0';
    
    // Parse command line
    char* token = strtok(buffer, " \t");
    while (token && argc < MAX_ARGS) {
        argv[argc++] = token;
        token = strtok(NULL, " \t");
    }
    
    if (argc == 0) {
        return 0;  // Empty command
    }
    
    // Find command handler
    for (const command_handler_t* cmd = command_table; cmd->command; cmd++) {
        if (strcmp(argv[0], cmd->command) == 0) {
            // Check argument count
            if (argc - 1 < cmd->min_args || argc - 1 > cmd->max_args) {
                printf("Error: Invalid number of arguments\n");
                printf("Usage: %s %s\n", cmd->command, cmd->description);
                return -1;
            }
            
            // Check authentication if required
            if (cmd->requires_auth && !is_authenticated()) {
                printf("Error: Authentication required\n");
                return -1;
            }
            
            // Execute command
            return cmd->handler(argc, argv);
        }
    }
    
    printf("Error: Unknown command '%s'\n", argv[0]);
    return -1;
}

Magic-1 Bootloader Technical Analysis - Part 18: Authentication and Security

Authentication System

The security system implements basic password protection and access control for sensitive bootloader operations.

Core Authentication Structures

#define AUTH_TOKEN_LENGTH 32
#define MAX_PASSWORD_LENGTH 64
#define SALT_LENGTH 16

typedef struct {
    uint8_t token[AUTH_TOKEN_LENGTH];
    uint32_t creation_time;
    uint32_t expiry_time;
} auth_token_t;

typedef struct {
    uint8_t hash[AUTH_TOKEN_LENGTH];
    uint8_t salt[SALT_LENGTH];
    uint8_t attempts;
    uint32_t lockout_until;
} auth_config_t;

Authentication Manager Implementation

#include "auth.h"
#include "crypto/sha256.h"

#define MAX_LOGIN_ATTEMPTS 3
#define LOCKOUT_DURATION 300  // 5 minutes in seconds

static auth_config_t auth_config;
static auth_token_t current_token;
static uint8_t is_authenticated_flag = 0;

int authenticate(const char* password) {
    uint8_t hash[AUTH_TOKEN_LENGTH];
    uint32_t current_time = get_rtc_time();
    
    // Check lockout
    if (auth_config.lockout_until > current_time) {
        printf("Account is locked. Try again in %d seconds\n", 
               auth_config.lockout_until - current_time);
        return -1;
    }
    
    // Calculate password hash with salt
    sha256_context ctx;
    sha256_init(&ctx);
    sha256_update(&ctx, (uint8_t*)password, strlen(password));
    sha256_update(&ctx, auth_config.salt, SALT_LENGTH);
    sha256_final(&ctx, hash);
    
    // Verify hash
    if (memcmp(hash, auth_config.hash, AUTH_TOKEN_LENGTH) == 0) {
        // Success - generate new auth token
        generate_random_bytes(current_token.token, AUTH_TOKEN_LENGTH);
        current_token.creation_time = current_time;
        current_token.expiry_time = current_time + 3600;  // 1 hour validity
        
        auth_config.attempts = 0;
        is_authenticated_flag = 1;
        return 0;
    }
    
    // Failed attempt
    auth_config.attempts++;
    if (auth_config.attempts >= MAX_LOGIN_ATTEMPTS) {
        auth_config.lockout_until = current_time + LOCKOUT_DURATION;
        auth_config.attempts = 0;
    }
    
    return -1;
}

Security Utilities

#include "auth.h"

void generate_random_bytes(uint8_t* buffer, size_t length) {
    // Use hardware RTC as entropy source
    uint32_t rtc_value;
    uint8_t entropy[4];
    
    for (size_t i = 0; i < length; i++) {
        if (i % 4 == 0) {
            rtc_value = get_rtc_time();
            memcpy(entropy, &rtc_value, 4);
        }
        buffer[i] = entropy[i % 4] ^ (i * 0x5A);  // Simple mixing function
    }
}

int change_password(const char* old_password, const char* new_password) {
    if (!is_authenticated() || strlen(new_password) > MAX_PASSWORD_LENGTH) {
        return -1;
    }
    
    // Verify old password first
    if (authenticate(old_password) != 0) {
        return -1;
    }
    
    // Generate new salt
    generate_random_bytes(auth_config.salt, SALT_LENGTH);
    
    // Hash new password
    sha256_context ctx;
    sha256_init(&ctx);
    sha256_update(&ctx, (uint8_t*)new_password, strlen(new_password));
    sha256_update(&ctx, auth_config.salt, SALT_LENGTH);
    sha256_final(&ctx, auth_config.hash);
    
    // Save configuration
    save_auth_config();
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 19: Hardware Abstraction Layer (HAL)

Core HAL Architecture

The HAL provides a uniform interface to hardware components while isolating platform-specific details.

Base HAL Interface

#pragma once
#include <stdint.h>

typedef enum {
    HAL_SUCCESS = 0,
    HAL_ERROR_INVALID_PARAM = -1,
    HAL_ERROR_NOT_INITIALIZED = -2,
    HAL_ERROR_HARDWARE = -3,
    HAL_ERROR_TIMEOUT = -4
} hal_status_t;

/* Core HAL interface functions */
typedef struct {
    /* System Control */
    void (*reset_system)(void);
    void (*halt_system)(void);
    void (*delay_ms)(uint32_t ms);
    
    /* Memory Management */
    void* (*mem_map)(uint32_t phys_addr, size_t size);
    void (*mem_unmap)(void* addr);
    
    /* Interrupt Management */
    void (*enable_irq)(uint8_t irq);
    void (*disable_irq)(uint8_t irq);
    
    /* I/O Operations */
    uint8_t (*read_io8)(uint16_t port);
    void (*write_io8)(uint16_t port, uint8_t value);
    uint16_t (*read_io16)(uint16_t port);
    void (*write_io16)(uint16_t port, uint16_t value);
} hal_ops_t;

Magic-1 HAL Implementation

#include "hal.h"

/* Hardware-specific definitions */
#define MAGIC1_CONTROL_REG   0xFFF0
#define MAGIC1_STATUS_REG    0xFFF2
#define MAGIC1_RESET_BIT     0x01
#define MAGIC1_HALT_BIT      0x02

static hal_ops_t magic1_hal_ops;

static void magic1_reset_system(void) {
    /* Set reset bit in control register */
    uint16_t ctrl = read_io16(MAGIC1_CONTROL_REG);
    write_io16(MAGIC1_CONTROL_REG, ctrl | MAGIC1_RESET_BIT);
    
    /* System should reset, but if we get here, halt */
    while(1) { }
}

static void magic1_delay_ms(uint32_t ms) {
    uint32_t cycles = ms * (CLOCK_FREQUENCY / 1000);
    while(cycles--) {
        __asm__ volatile("nop");
    }
}

/* Initialize HAL operations structure */
void hal_init(void) {
    magic1_hal_ops.reset_system = magic1_reset_system;
    magic1_hal_ops.halt_system = magic1_halt_system;
    magic1_hal_ops.delay_ms = magic1_delay_ms;
    magic1_hal_ops.mem_map = magic1_mem_map;
    magic1_hal_ops.mem_unmap = magic1_mem_unmap;
    magic1_hal_ops.enable_irq = magic1_enable_irq;
    magic1_hal_ops.disable_irq = magic1_disable_irq;
    magic1_hal_ops.read_io8 = magic1_read_io8;
    magic1_hal_ops.write_io8 = magic1_write_io8;
    magic1_hal_ops.read_io16 = magic1_read_io16;
    magic1_hal_ops.write_io16 = magic1_write_io16;
}

HAL Unit Tests

#include "unity.h"
#include "hal.h"

void setUp(void) {
    hal_init();
}

void tearDown(void) {
    /* Nothing to clean up */
}

void test_io_operations(void) {
    /* Test 8-bit I/O */
    write_io8(0xFF00, 0x55);
    TEST_ASSERT_EQUAL_UINT8(0x55, read_io8(0xFF00));
    
    /* Test 16-bit I/O */
    write_io16(0xFF02, 0xAA55);
    TEST_ASSERT_EQUAL_UINT16(0xAA55, read_io16(0xFF02));
}

void test_interrupt_management(void) {
    /* Test IRQ enable/disable */
    enable_irq(1);
    TEST_ASSERT_BIT_HIGH(read_io16(MAGIC1_STATUS_REG), 1);
    
    disable_irq(1);
    TEST_ASSERT_BIT_LOW(read_io16(MAGIC1_STATUS_REG), 1);
}

Magic-1 Bootloader Technical Analysis - Part 20: Power Management and System Control

System Control Architecture

The power management and system control module handles system states, power modes, and hardware configuration.

Core Power Management Interface

#pragma once
#include <stdint.h>

/* System power states */
typedef enum {
    POWER_STATE_RUN,      // Normal operation
    POWER_STATE_IDLE,     // CPU idle, peripherals active
    POWER_STATE_STANDBY,  // Low power mode, quick wake
    POWER_STATE_SHUTDOWN  // Full power down
} power_state_t;

/* Clock configuration */
typedef struct {
    uint8_t  pll_multiplier;  // 1-16
    uint8_t  pll_divider;     // 1-8
    uint8_t  cpu_divider;     // 1-8
    uint8_t  periph_divider;  // 1-8
    uint32_t target_freq;     // Desired CPU frequency
} clock_config_t;

Power Management Implementation

#include "power_mgmt.h"

#define POWER_CTRL_REG    0xFFF4
#define CLOCK_CTRL_REG    0xFFF6
#define STATUS_REG        0xFFF8

#define PWR_MODE_MASK     0x03
#define PLL_LOCK_BIT      0x80
#define CLK_STABLE_BIT    0x40

static power_state_t current_power_state = POWER_STATE_RUN;
static clock_config_t current_clock_config;

int set_power_state(power_state_t new_state) {
    uint16_t ctrl_reg;
    
    if (new_state == current_power_state) {
        return 0;  // Already in requested state
    }
    
    // Read current control register
    ctrl_reg = read_io16(POWER_CTRL_REG);
    
    // Clear power mode bits
    ctrl_reg &= ~PWR_MODE_MASK;
    
    // Set new power mode
    switch (new_state) {
        case POWER_STATE_RUN:
            ctrl_reg |= 0x00;
            break;
            
        case POWER_STATE_IDLE:
            ctrl_reg |= 0x01;
            break;
            
        case POWER_STATE_STANDBY:
            ctrl_reg |= 0x02;
            break;
            
        case POWER_STATE_SHUTDOWN:
            ctrl_reg |= 0x03;
            break;
            
        default:
            return -1;
    }
    
    // Update control register
    write_io16(POWER_CTRL_REG, ctrl_reg);
    
    // Wait for state change to complete
    while ((read_io16(STATUS_REG) & PWR_MODE_MASK) != 
           (ctrl_reg & PWR_MODE_MASK)) {
        // Timeout check could be added here
    }
    
    current_power_state = new_state;
    return 0;
}

Clock Management Module

#include "power_mgmt.h"

int configure_system_clock(const clock_config_t* config) {
    uint16_t clock_ctrl;
    uint32_t timeout = 1000;  // Timeout counter
    
    // Validate configuration
    if (!config || config->pll_multiplier > 16 || 
        config->pll_divider > 8 || config->cpu_divider > 8) {
        return -1;
    }
    
    // Build clock control value
    clock_ctrl = ((config->pll_multiplier - 1) << 12) |
                ((config->pll_divider - 1) << 9) |
                ((config->cpu_divider - 1) << 6) |
                ((config->periph_divider - 1) << 3);
                
    // Update clock control register
    write_io16(CLOCK_CTRL_REG, clock_ctrl);
    
    // Wait for PLL lock and clock stabilization
    while (timeout--) {
        if ((read_io16(STATUS_REG) & (PLL_LOCK_BIT | CLK_STABLE_BIT)) ==
            (PLL_LOCK_BIT | CLK_STABLE_BIT)) {
            memcpy(&current_clock_config, config, sizeof(clock_config_t));
            return 0;
        }
    }
    
    return -1;  // Timeout waiting for clock stabilization
}

Magic-1 Bootloader Technical Analysis - Part 21: Boot Image Format and Verification

Boot Image Structure and Management

Boot Image Header Definition

The boot image format follows a strict structure for reliability and security:

#define MAGIC_NUMBER     0x4D31    // "M1"
#define IMAGE_VERSION    0x0001
#define MAX_IMAGE_NAME   32
#define MAX_SIGNATURES   4

typedef struct {
    uint16_t magic;              // Magic number identifier
    uint16_t version;           // Image format version
    uint32_t total_size;        // Total image size including header
    uint32_t entry_point;       // Entry point address
    uint32_t load_address;      // Load address
    uint32_t code_size;         // Size of code segment
    uint32_t data_size;         // Size of data segment
    uint32_t bss_size;          // Size of BSS segment
    uint32_t symbol_offset;     // Offset to symbol table
    uint32_t reloc_offset;      // Offset to relocation table
    uint8_t  flags;             // Image flags
    uint8_t  cpu_type;          // Target CPU type
    char     name[MAX_IMAGE_NAME]; // Image name
    uint8_t  signatures[MAX_SIGNATURES][64]; // Digital signatures
    uint32_t checksum;          // CRC32 of image excluding header
} __attribute__((packed)) boot_image_header_t;

Image Verification Implementation

#include "boot_image.h"
#include "crypto/crc32.h"
#include "crypto/sha256.h"

static const uint8_t public_key[32] = {
    0x55, 0xAA, /* ... public key data ... */
};

int verify_boot_image(const void* image_data, size_t size) {
    const boot_image_header_t* header = (const boot_image_header_t*)image_data;
    uint32_t computed_crc;
    
    // Verify minimum size
    if (size < sizeof(boot_image_header_t)) {
        return -1;
    }
    
    // Check magic number and version
    if (header->magic != MAGIC_NUMBER || 
        header->version != IMAGE_VERSION) {
        return -2;
    }
    
    // Verify total size
    if (size < header->total_size) {
        return -3;
    }
    
    // Calculate and verify checksum
    computed_crc = crc32(0, 
        (uint8_t*)image_data + sizeof(boot_image_header_t),
        header->total_size - sizeof(boot_image_header_t));
        
    if (computed_crc != header->checksum) {
        return -4;
    }
    
    // Verify digital signatures if present
    if (header->flags & IMAGE_FLAG_SIGNED) {
        if (verify_signatures(header) != 0) {
            return -5;
        }
    }
    
    return 0;
}

Image Loading and Processing

#include "boot_image.h"
#include "memory/mmu.h"

int load_boot_image(const void* image_data) {
    const boot_image_header_t* header = (const boot_image_header_t*)image_data;
    const uint8_t* data = (const uint8_t*)image_data;
    void* load_addr;
    
    // First verify the image
    if (verify_boot_image(image_data, header->total_size) != 0) {
        return -1;
    }
    
    // Allocate and map memory
    load_addr = mmu_map_region(header->load_address, 
                              header->total_size,
                              MMU_FLAG_READ | MMU_FLAG_WRITE | MMU_FLAG_EXEC);
                              
    if (!load_addr) {
        return -2;
    }
    
    // Copy code segment
    memcpy((void*)header->load_address,
           data + sizeof(boot_image_header_t),
           header->code_size);
           
    // Copy data segment
    memcpy((void*)(header->load_address + header->code_size),
           data + sizeof(boot_image_header_t) + header->code_size,
           header->data_size);
           
    // Clear BSS segment
    memset((void*)(header->load_address + header->code_size + header->data_size),
           0,
           header->bss_size);
           
    // Process relocations if present
    if (header->reloc_offset) {
        process_relocations(header);
    }
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 22: System Initialization and Boot Process

Initial Boot Sequence

The system initialization process follows a carefully orchestrated sequence of steps to bring the Magic-1 hardware to a known good state.

Core Initialization Sequence

#define INIT_FLAG_MMU_ENABLED    (1 << 0)
#define INIT_FLAG_CACHE_ENABLED  (1 << 1)
#define INIT_FLAG_INTERRUPTS_ON  (1 << 2)

typedef enum {
    BOOT_PHASE_RESET,
    BOOT_PHASE_EARLY_INIT,
    BOOT_PHASE_HARDWARE_INIT,
    BOOT_PHASE_MEMORY_INIT,
    BOOT_PHASE_DEVICE_INIT,
    BOOT_PHASE_FINAL_INIT
} boot_phase_t;

typedef struct {
    boot_phase_t current_phase;
    uint32_t flags;
    uint32_t boot_time;
    uint32_t error_code;
} boot_state_t;

Early Initialization Assembly

        .section .text.init
        .global _start
_start:
        # Disable interrupts
        cli
        
        # Set up initial stack
        ldi     sp, #0x8000
        
        # Clear BSS section
        ldi     a0, #__bss_start
        ldi     a1, #__bss_end
        ldi     a2, #0
clear_bss:
        cmp     a0, a1
        beq     bss_done
        st      a2, (a0)
        inc     a0
        br      clear_bss
bss_done:

        # Jump to C initialization
        call    boot_init

Main Boot Initialization

static boot_state_t boot_state = {
    .current_phase = BOOT_PHASE_RESET,
    .flags = 0,
    .boot_time = 0,
    .error_code = 0
};

void boot_init(void) {
    // Early hardware initialization
    early_hw_init();
    boot_state.current_phase = BOOT_PHASE_EARLY_INIT;
    
    // Initialize memory subsystem
    if (init_memory() != 0) {
        boot_state.error_code = ERR_MEMORY_INIT;
        panic();
    }
    boot_state.current_phase = BOOT_PHASE_MEMORY_INIT;
    
    // Enable MMU
    if (mmu_init() == 0) {
        boot_state.flags |= INIT_FLAG_MMU_ENABLED;
    }
    
    // Initialize essential devices
    init_uart();
    init_timer();
    init_interrupt_controller();
    
    boot_state.current_phase = BOOT_PHASE_DEVICE_INIT;
    
    // Enable interrupts
    sti();
    boot_state.flags |= INIT_FLAG_INTERRUPTS_ON;
    
    // Jump to main bootloader code
    bootloader_main();
}

Magic-1 Bootloader Technical Analysis - Part 23: Memory Management and Cache Control

Memory Management System

The Magic-1's memory management system handles address translation, cache control, and memory protection.

Memory Manager Core Interface

#include <stdint.h>

/* Memory protection flags */
#define MEM_PROT_READ    (1 << 0)
#define MEM_PROT_WRITE   (1 << 1)
#define MEM_PROT_EXEC    (1 << 2)

/* Memory type definitions */
#define MEM_TYPE_RAM     0
#define MEM_TYPE_ROM     1
#define MEM_TYPE_DEVICE  2

struct memory_region {
    uint32_t start;          /* Start address */
    uint32_t size;           /* Region size */
    uint8_t  type;          /* Memory type */
    uint8_t  protection;    /* Protection flags */
    uint8_t  cacheable;     /* Cache enable flag */
    char     name[16];      /* Region name */
};

Cache Control Implementation

#define CACHE_CTRL_REG   0xFFF2
#define CACHE_FLUSH_BIT  0x01
#define CACHE_ENABLE_BIT 0x02

void flush_cache(void) {
    uint16_t ctrl;
    
    /* Read current cache control */
    ctrl = read_io16(CACHE_CTRL_REG);
    
    /* Set flush bit */
    write_io16(CACHE_CTRL_REG, ctrl | CACHE_FLUSH_BIT);
    
    /* Wait for flush to complete */
    while(read_io16(CACHE_CTRL_REG) & CACHE_FLUSH_BIT) {
        /* Busy wait */
    }
}

int configure_cache(int enable) {
    uint16_t ctrl = read_io16(CACHE_CTRL_REG);
    
    if(enable) {
        ctrl |= CACHE_ENABLE_BIT;
    } else {
        ctrl &= ~CACHE_ENABLE_BIT;
    }
    
    write_io16(CACHE_CTRL_REG, ctrl);
    return 0;
}

Memory Region Management

#define MAX_MEMORY_REGIONS 16

static struct memory_region regions[MAX_MEMORY_REGIONS];
static int num_regions = 0;

int register_memory_region(const struct memory_region *region) {
    if(num_regions >= MAX_MEMORY_REGIONS) {
        return -1;
    }
    
    /* Check for overlap with existing regions */
    for(int i = 0; i < num_regions; i++) {
        if((region->start < (regions[i].start + regions[i].size)) &&
           ((region->start + region->size) > regions[i].start)) {
            return -2;
        }
    }
    
    /* Add new region */
    memcpy(&regions[num_regions], region, sizeof(struct memory_region));
    num_regions++;
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 24: Interrupt Management System

Interrupt Controller Architecture

The Magic-1's interrupt system provides prioritized hardware and software interrupt handling with nested interrupt support.

Core Interrupt Definitions

#define MAX_INTERRUPTS 16
#define IRQ_LEVELS     8

/* Interrupt vector definitions */
#define IRQ_NMI        0   /* Non-maskable interrupt */
#define IRQ_TIMER      1   /* System timer */
#define IRQ_UART0      2   /* Primary UART */
#define IRQ_UART1      3   /* Secondary UART */
#define IRQ_IDE        4   /* IDE interface */
#define IRQ_RTC        5   /* Real-time clock */
#define IRQ_FAULT      6   /* CPU fault */
#define IRQ_TRAP       7   /* Software trap */

/* Interrupt priority levels */
typedef enum {
    IPL_NONE = 0,
    IPL_LOW  = 1,
    IPL_MED  = 4,
    IPL_HIGH = 6,
    IPL_NMI  = 7
} ipl_t;

Vector Table Implementation

#include "interrupts.h"

typedef struct {
    void (*handler)(void);
    ipl_t priority;
    uint32_t count;
    const char *name;
} vector_entry_t;

static vector_entry_t vector_table[MAX_INTERRUPTS] = {
    [IRQ_NMI]   = { nmi_handler,   IPL_NMI,  0, "NMI" },
    [IRQ_TIMER] = { timer_handler, IPL_HIGH, 0, "Timer" },
    [IRQ_UART0] = { uart0_handler, IPL_MED,  0, "UART0" },
    [IRQ_UART1] = { uart1_handler, IPL_MED,  0, "UART1" },
    [IRQ_IDE]   = { ide_handler,   IPL_LOW,  0, "IDE" },
    [IRQ_RTC]   = { rtc_handler,   IPL_LOW,  0, "RTC" },
    [IRQ_FAULT] = { fault_handler, IPL_NMI,  0, "Fault" },
    [IRQ_TRAP]  = { trap_handler,  IPL_HIGH, 0, "Trap" }
};

/* Initialize vector table in hardware */
void init_vectors(void) {
    for(int i = 0; i < MAX_INTERRUPTS; i++) {
        if(vector_table[i].handler) {
            write_vector(i, vector_table[i].handler);
            set_vector_priority(i, vector_table[i].priority);
        }
    }
}

Interrupt Controller Management

#define INT_CTRL_BASE   0xFFC0
#define INT_MASK_REG    (INT_CTRL_BASE + 0)
#define INT_STATUS_REG  (INT_CTRL_BASE + 2)
#define INT_ACK_REG     (INT_CTRL_BASE + 4)
#define INT_PRIO_REG    (INT_CTRL_BASE + 6)

static uint16_t interrupt_mask = 0;
static uint8_t current_ipl = IPL_NONE;

void enable_interrupt(uint8_t irq) {
    if(irq < MAX_INTERRUPTS) {
        interrupt_mask |= (1 << irq);
        write_io16(INT_MASK_REG, interrupt_mask);
    }
}

void set_ipl(uint8_t level) {
    current_ipl = level;
    write_io16(INT_PRIO_REG, level);
}

void interrupt_dispatch(void) {
    uint16_t active = read_io16(INT_STATUS_REG);
    
    for(int i = 0; i < MAX_INTERRUPTS; i++) {
        if(active & (1 << i)) {
            if(vector_table[i].handler && 
               vector_table[i].priority > current_ipl) {
                vector_table[i].count++;
                vector_table[i].handler();
            }
            write_io16(INT_ACK_REG, 1 << i);
        }
    }
}

Magic-1 Bootloader Technical Analysis - Part 25: Device Drivers and Hardware Interface Layer

Device Driver Framework

The Magic-1 hardware abstraction employs a modular driver system for managing various hardware components.

Core Driver Interface

#include <stdint.h>

typedef enum {
    DRIVER_STATUS_OK = 0,
    DRIVER_STATUS_ERROR = -1,
    DRIVER_STATUS_TIMEOUT = -2,
    DRIVER_STATUS_NOT_SUPPORTED = -3
} driver_status_t;

typedef struct device_driver {
    const char* name;
    uint32_t base_address;
    uint32_t irq_number;
    
    /* Driver operations */
    int (*init)(struct device_driver* driver);
    int (*read)(struct device_driver* driver, void* buffer, size_t size);
    int (*write)(struct device_driver* driver, const void* buffer, size_t size);
    int (*ioctl)(struct device_driver* driver, uint32_t cmd, void* arg);
    void (*irq_handler)(struct device_driver* driver);
    void (*shutdown)(struct device_driver* driver);
    
    /* Private data */
    void* private_data;
} device_driver_t;

UART Driver Implementation

#include "driver_interface.h"

#define UART_RBR 0x00   /* Receive Buffer Register */
#define UART_THR 0x00   /* Transmit Holding Register */
#define UART_IER 0x01   /* Interrupt Enable Register */
#define UART_FCR 0x02   /* FIFO Control Register */
#define UART_LCR 0x03   /* Line Control Register */
#define UART_LSR 0x05   /* Line Status Register */

typedef struct {
    uint8_t tx_fifo[16];
    uint8_t rx_fifo[16];
    uint8_t tx_head;
    uint8_t tx_tail;
    uint8_t rx_head;
    uint8_t rx_tail;
} uart_private_t;

static int uart_init(device_driver_t* driver) {
    uint16_t base = driver->base_address;
    
    /* Initialize UART hardware */
    outb(base + UART_LCR, 0x80);    /* Enable DLAB */
    outb(base + UART_RBR, 0x0C);    /* Baud rate divisor */
    outb(base + UART_IER, 0x00);
    outb(base + UART_LCR, 0x03);    /* 8N1 */
    outb(base + UART_FCR, 0x07);    /* Enable and clear FIFOs */
    
    /* Allocate private data */
    driver->private_data = malloc(sizeof(uart_private_t));
    memset(driver->private_data, 0, sizeof(uart_private_t));
    
    return DRIVER_STATUS_OK;
}

IDE Controller Driver

#include "driver_interface.h"

#define IDE_DATA    0x00
#define IDE_ERROR   0x01
#define IDE_STATUS  0x07
#define IDE_COMMAND 0x07

typedef struct {
    uint8_t is_present;
    uint8_t is_master;
    uint16_t cylinders;
    uint16_t heads;
    uint16_t sectors;
} ide_private_t;

static int ide_init(device_driver_t* driver) {
    uint16_t base = driver->base_address;
    ide_private_t* priv;
    
    /* Allocate private data */
    driver->private_data = malloc(sizeof(ide_private_t));
    priv = (ide_private_t*)driver->private_data;
    
    /* Detect drive presence */
    outb(base + IDE_COMMAND, 0xEC);  /* IDENTIFY command */
    if (inb(base + IDE_STATUS) == 0) {
        priv->is_present = 0;
        return DRIVER_STATUS_ERROR;
    }
    
    /* Read identification data */
    for (int i = 0; i < 256; i++) {
        uint16_t data = inw(base + IDE_DATA);
        /* Process identification data */
    }
    
    return DRIVER_STATUS_OK;
}

Magic-1 Bootloader Technical Analysis - Part 26: File System Support

File System Layer Implementation

The Magic-1 bootloader implements a minimal file system layer to handle boot images and configuration files.

Core File System Interface

#define FS_MAX_PATH      256
#define FS_MAX_NAME      64
#define FS_MAX_OPEN      8
#define FS_SECTOR_SIZE   512

typedef enum {
    FS_TYPE_NONE = 0,
    FS_TYPE_FAT16,
    FS_TYPE_FAT32,
    FS_TYPE_M1FS
} fs_type_t;

typedef struct {
    char     name[FS_MAX_NAME];
    uint32_t size;
    uint32_t start_sector;
    uint8_t  attributes;
    uint32_t create_time;
    uint32_t modify_time;
} fs_entry_t;

M1FS (Magic-1 File System) Implementation

#define M1FS_MAGIC       0x4D314653  // "M1FS"
#define M1FS_VERSION     0x0100
#define M1FS_BLOCK_SIZE  2048

struct m1fs_superblock {
    uint32_t magic;
    uint16_t version;
    uint16_t block_size;
    uint32_t total_blocks;
    uint32_t free_blocks;
    uint32_t root_block;
    uint8_t  label[16];
    uint8_t  reserved[32];
} __attribute__((packed));

struct m1fs_directory_entry {
    char     name[FS_MAX_NAME];
    uint32_t first_block;
    uint32_t size;
    uint8_t  type;
    uint8_t  attributes;
    uint32_t create_time;
    uint32_t modify_time;
    uint8_t  reserved[16];
} __attribute__((packed));

File Operations Implementation

typedef struct {
    fs_entry_t entry;
    uint32_t position;
    uint8_t  mode;
    uint8_t  dirty;
    uint8_t* buffer;
} file_handle_t;

static file_handle_t open_files[FS_MAX_OPEN];

int fs_open(const char* path, uint8_t mode) {
    int handle = -1;
    fs_entry_t entry;
    
    // Find free handle
    for(int i = 0; i < FS_MAX_OPEN; i++) {
        if(!open_files[i].buffer) {
            handle = i;
            break;
        }
    }
    
    if(handle < 0) {
        return -1; // No free handles
    }
    
    // Look up file entry
    if(fs_lookup(path, &entry) != 0) {
        return -2; // File not found
    }
    
    // Initialize handle
    open_files[handle].entry = entry;
    open_files[handle].position = 0;
    open_files[handle].mode = mode;
    open_files[handle].dirty = 0;
    open_files[handle].buffer = malloc(FS_SECTOR_SIZE);
    
    return handle;
}

Magic-1 Bootloader Technical Analysis - Part 27: Configuration Management

The configuration management system handles bootloader settings, system parameters, and hardware configuration.

Core Configuration System

Configuration Data Structures

#define CONFIG_MAGIC    0x4D314346  // "M1CF"
#define MAX_CONFIG_SIZE 4096
#define MAX_KEY_LENGTH  32
#define MAX_VAL_LENGTH  128

typedef struct config_entry {
    char key[MAX_KEY_LENGTH];
    char value[MAX_VAL_LENGTH];
    struct config_entry* next;
} config_entry_t;

typedef struct {
    uint32_t magic;
    uint16_t version;
    uint16_t num_entries;
    uint32_t checksum;
    config_entry_t* entries;
} config_data_t;

Configuration Storage Manager

static config_data_t config;

int save_config(void) {
    uint8_t buffer[MAX_CONFIG_SIZE];
    uint32_t offset = 0;
    config_entry_t* entry;
    
    // Write header
    memcpy(buffer + offset, &config.magic, sizeof(uint32_t));
    offset += sizeof(uint32_t);
    memcpy(buffer + offset, &config.version, sizeof(uint16_t));
    offset += sizeof(uint16_t);
    memcpy(buffer + offset, &config.num_entries, sizeof(uint16_t));
    offset += sizeof(uint16_t);
    
    // Write entries
    for(entry = config.entries; entry; entry = entry->next) {
        uint8_t key_len = strlen(entry->key);
        uint8_t val_len = strlen(entry->value);
        
        buffer[offset++] = key_len;
        memcpy(buffer + offset, entry->key, key_len);
        offset += key_len;
        
        buffer[offset++] = val_len;
        memcpy(buffer + offset, entry->value, val_len);
        offset += val_len;
    }
    
    // Calculate and write checksum
    config.checksum = calculate_crc32(buffer, offset);
    memcpy(buffer + offset, &config.checksum, sizeof(uint32_t));
    offset += sizeof(uint32_t);
    
    // Write to storage
    return write_config_sector(buffer, offset);
}

Configuration API Implementation

const char* config_get(const char* key) {
    config_entry_t* entry;
    
    for(entry = config.entries; entry; entry = entry->next) {
        if(strcmp(entry->key, key) == 0) {
            return entry->value;
        }
    }
    
    return NULL;
}

int config_set(const char* key, const char* value) {
    config_entry_t* entry;
    
    // Look for existing entry
    for(entry = config.entries; entry; entry = entry->next) {
        if(strcmp(entry->key, key) == 0) {
            strncpy(entry->value, value, MAX_VAL_LENGTH - 1);
            entry->value[MAX_VAL_LENGTH - 1] = '\0';
            return 0;
        }
    }
    
    // Create new entry
    entry = malloc(sizeof(config_entry_t));
    if(!entry) {
        return -1;
    }
    
    strncpy(entry->key, key, MAX_KEY_LENGTH - 1);
    entry->key[MAX_KEY_LENGTH - 1] = '\0';
    strncpy(entry->value, value, MAX_VAL_LENGTH - 1);
    entry->value[MAX_VAL_LENGTH - 1] = '\0';
    
    // Add to list
    entry->next = config.entries;
    config.entries = entry;
    config.num_entries++;
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 28: System Diagnostics and Debug Support

Debug Framework Implementation

Core Debug Interface

First, let's define our debug interface structures:

#define DEBUG_BUFFER_SIZE 1024
#define MAX_BREAKPOINTS 8
#define MAX_WATCHPOINTS 4

typedef enum {
    DEBUG_LEVEL_NONE = 0,
    DEBUG_LEVEL_ERROR,
    DEBUG_LEVEL_WARN,
    DEBUG_LEVEL_INFO,
    DEBUG_LEVEL_DEBUG
} debug_level_t;

typedef struct {
    uint16_t address;
    uint16_t original_opcode;
    bool enabled;
    char description[32];
} breakpoint_t;

typedef struct {
    uint16_t address;
    uint16_t size;
    uint16_t last_value;
    bool enabled;
    void (*callback)(uint16_t addr, uint16_t old_val, uint16_t new_val);
} watchpoint_t;

Debug Manager Implementation

static struct {
    debug_level_t current_level;
    breakpoint_t breakpoints[MAX_BREAKPOINTS];
    watchpoint_t watchpoints[MAX_WATCHPOINTS];
    char debug_buffer[DEBUG_BUFFER_SIZE];
    uint16_t buffer_pos;
    bool single_step_mode;
} debug_context;

void debug_init(void) {
    debug_context.current_level = DEBUG_LEVEL_INFO;
    debug_context.buffer_pos = 0;
    debug_context.single_step_mode = false;
    
    // Install debug trap handler
    install_trap_handler(debug_trap_handler);
}

int set_breakpoint(uint16_t addr, const char* desc) {
    for (int i = 0; i < MAX_BREAKPOINTS; i++) {
        if (!debug_context.breakpoints[i].enabled) {
            debug_context.breakpoints[i].address = addr;
            debug_context.breakpoints[i].original_opcode = read_memory(addr);
            debug_context.breakpoints[i].enabled = true;
            strncpy(debug_context.breakpoints[i].description, desc, 31);
            
            // Replace instruction with trap
            write_memory(addr, 0xFFFF);  // TRAP instruction
            return i;
        }
    }
    return -1;  // No free breakpoints
}

Memory Inspection and Modification Tools

void dump_memory(uint16_t start, uint16_t length) {
    for (uint16_t addr = start; addr < start + length; addr += 16) {
        printf("%04X: ", addr);
        
        // Hex display
        for (int i = 0; i < 16; i++) {
            if (i == 8) printf("- ");
            printf("%02X ", read_memory(addr + i));
        }
        
        printf(" |");
        // ASCII display
        for (int i = 0; i < 16; i++) {
            uint8_t byte = read_memory(addr + i);
            printf("%c", (byte >= 32 && byte <= 126) ? byte : '.');
        }
        printf("|\n");
    }
}

void modify_memory(uint16_t addr, uint8_t value) {
    if (is_memory_protected(addr)) {
        debug_printf(DEBUG_LEVEL_ERROR, 
                    "Cannot modify protected memory at %04X\n", addr);
        return;
    }
    write_memory(addr, value);
}

Magic-1 Bootloader Technical Analysis - Part 29: User Interface and Command Processing

Command Line Interface Implementation

Command Interpreter Core

First, let's define the command structure:

#define MAX_CMD_LENGTH  32
#define MAX_ARGS        8
#define MAX_HELP_TEXT  128

typedef struct command {
    const char* name;
    const char* help_text;
    int min_args;
    int max_args;
    int (*handler)(int argc, char* argv[]);
    bool requires_auth;
} command_t;

typedef enum {
    CMD_SUCCESS = 0,
    CMD_ERROR = -1,
    CMD_NOT_FOUND = -2,
    CMD_INVALID_ARGS = -3,
    CMD_AUTH_REQUIRED = -4
} cmd_result_t;

Command Processing Engine

static const command_t commands[] = {
    {
        .name = "boot",
        .help_text = "boot <image_name> - Boot specified system image",
        .min_args = 1,
        .max_args = 1,
        .handler = cmd_boot_handler,
        .requires_auth = true
    },
    {
        .name = "show",
        .help_text = "show <config|memory|devices> - Display system information",
        .min_args = 1,
        .max_args = 2,
        .handler = cmd_show_handler,
        .requires_auth = false
    },
    // Null terminator
    {NULL, NULL, 0, 0, NULL, false}
};

static cmd_result_t process_command_line(const char* input) {
    char buffer[MAX_CMD_LENGTH];
    char* args[MAX_ARGS];
    int argc = 0;
    
    // Skip leading whitespace
    while (*input && isspace(*input)) input++;
    
    if (*input == '\0') return CMD_SUCCESS;  // Empty line
    
    // Parse command and arguments
    strncpy(buffer, input, MAX_CMD_LENGTH - 1);
    buffer[MAX_CMD_LENGTH - 1] = '\0';
    
    char* token = strtok(buffer, " \t");
    while (token && argc < MAX_ARGS) {
        args[argc++] = token;
        token = strtok(NULL, " \t");
    }
    
    // Find and execute command
    for (const command_t* cmd = commands; cmd->name; cmd++) {
        if (strcmp(args[0], cmd->name) == 0) {
            if (argc - 1 < cmd->min_args || argc - 1 > cmd->max_args) {
                printf("Error: Invalid number of arguments\n");
                printf("Usage: %s\n", cmd->help_text);
                return CMD_INVALID_ARGS;
            }
            
            if (cmd->requires_auth && !is_authenticated()) {
                printf("Error: Authentication required\n");
                return CMD_AUTH_REQUIRED;
            }
            
            return cmd->handler(argc, args);
        }
    }
    
    printf("Error: Unknown command '%s'\n", args[0]);
    return CMD_NOT_FOUND;
}

Magic-1 Bootloader Technical Analysis - Part 30: Error Recovery and System Resilience

Error Recovery System

The Magic-1 bootloader implements a robust error recovery mechanism to handle hardware failures, corrupted data, and system faults.

Error Recovery Manager

#define MAX_RECOVERY_ATTEMPTS 3
#define RECOVERY_LOG_SIZE    16

typedef enum {
    RECOVERY_STATE_NORMAL,
    RECOVERY_STATE_ATTEMPTING,
    RECOVERY_STATE_FAILED,
    RECOVERY_STATE_SUCCESS
} recovery_state_t;

typedef struct {
    uint32_t timestamp;
    uint16_t error_code;
    uint8_t  attempted_fixes;
    recovery_state_t outcome;
} recovery_log_entry_t;

Recovery Implementation

static struct {
    recovery_state_t current_state;
    uint8_t attempt_count;
    recovery_log_entry_t log[RECOVERY_LOG_SIZE];
    uint8_t log_index;
} recovery_context;

int attempt_recovery(uint16_t error_code) {
    recovery_log_entry_t* entry;
    
    if (recovery_context.attempt_count >= MAX_RECOVERY_ATTEMPTS) {
        enter_fail_safe_mode();
        return -1;
    }
    
    // Log recovery attempt
    entry = &recovery_context.log[recovery_context.log_index];
    entry->timestamp = get_system_time();
    entry->error_code = error_code;
    entry->attempted_fixes = recovery_context.attempt_count + 1;
    
    recovery_context.current_state = RECOVERY_STATE_ATTEMPTING;
    
    // Attempt recovery based on error code
    switch (error_code) {
        case ERR_CORRUPT_CONFIG:
            if (restore_backup_config() == 0) {
                entry->outcome = RECOVERY_STATE_SUCCESS;
                return 0;
            }
            break;
            
        case ERR_BOOT_IMAGE:
            if (try_alternate_boot_image() == 0) {
                entry->outcome = RECOVERY_STATE_SUCCESS;
                return 0;
            }
            break;
            
        case ERR_HARDWARE_TIMEOUT:
            if (reset_hardware_interface() == 0) {
                entry->outcome = RECOVERY_STATE_SUCCESS;
                return 0;
            }
            break;
    }
    
    entry->outcome = RECOVERY_STATE_FAILED;
    recovery_context.attempt_count++;
    recovery_context.log_index = (recovery_context.log_index + 1) % RECOVERY_LOG_SIZE;
    
    return -1;
}

Magic-1 Bootloader Technical Analysis - Part 31: System Performance Monitoring

Performance Monitor Implementation

The performance monitoring system tracks system metrics and provides diagnostic information for bootloader optimization.

Core Performance Monitoring Structures

#define MAX_PERF_COUNTERS    16
#define MAX_PERF_EVENTS      32
#define PERF_SAMPLE_WINDOW   1000  // ms

typedef enum {
    PERF_METRIC_BOOT_TIME,
    PERF_METRIC_DISK_OPS,
    PERF_METRIC_CACHE_HITS,
    PERF_METRIC_CACHE_MISSES,
    PERF_METRIC_IRQ_COUNT,
    PERF_METRIC_ERROR_COUNT
} perf_metric_t;

typedef struct {
    perf_metric_t type;
    const char* name;
    uint32_t value;
    uint32_t min;
    uint32_t max;
    uint32_t samples[PERF_SAMPLE_WINDOW];
} perf_counter_t;

Performance Monitor Implementation

static struct {
    perf_counter_t counters[MAX_PERF_COUNTERS];
    uint8_t counter_count;
    uint32_t start_time;
    bool monitoring_active;
} perf_context;

void init_performance_monitor(void) {
    memset(&perf_context, 0, sizeof(perf_context));
    perf_context.start_time = get_system_time();
    
    // Register default counters
    register_perf_counter(PERF_METRIC_BOOT_TIME, "Boot Time");
    register_perf_counter(PERF_METRIC_DISK_OPS, "Disk Operations");
    register_perf_counter(PERF_METRIC_CACHE_HITS, "Cache Hits");
    register_perf_counter(PERF_METRIC_CACHE_MISSES, "Cache Misses");
    
    perf_context.monitoring_active = true;
}

void update_perf_counter(perf_metric_t metric, uint32_t value) {
    for (int i = 0; i < perf_context.counter_count; i++) {
        perf_counter_t* counter = &perf_context.counters[i];
        if (counter->type == metric) {
            counter->value = value;
            if (value < counter->min) counter->min = value;
            if (value > counter->max) counter->max = value;
            
            // Update rolling window
            uint32_t index = get_system_time() % PERF_SAMPLE_WINDOW;
            counter->samples[index] = value;
            break;
        }
    }
}

Performance Report Generation

void generate_performance_report(void) {
    printf("\nPerformance Monitor Report\n");
    printf("=========================\n");
    printf("System uptime: %d ms\n\n", get_system_time() - perf_context.start_time);
    
    for (int i = 0; i < perf_context.counter_count; i++) {
        perf_counter_t* counter = &perf_context.counters[i];
        printf("%-20s: current=%d, min=%d, max=%d\n",
               counter->name,
               counter->value,
               counter->min,
               counter->max);
    }
}

Magic-1 Bootloader Technical Analysis - Part 32: System State Management

State Management Architecture

The Magic-1 bootloader implements a comprehensive state management system to track and control system behavior during the boot process.

Core State Definitions

#define MAX_STATE_TRANSITIONS 16
#define MAX_STATE_HANDLERS    32

typedef enum {
    SYSTEM_STATE_RESET,
    SYSTEM_STATE_EARLY_INIT,
    SYSTEM_STATE_HW_DETECT,
    SYSTEM_STATE_MEMORY_INIT,
    SYSTEM_STATE_DEVICE_INIT,
    SYSTEM_STATE_BOOT_SELECT,
    SYSTEM_STATE_LOADING,
    SYSTEM_STATE_READY,
    SYSTEM_STATE_ERROR,
    SYSTEM_STATE_RECOVERY
} system_state_t;

typedef struct {
    system_state_t current;
    system_state_t previous;
    uint32_t state_entry_time;
    uint32_t state_duration;
    uint8_t error_count;
    bool recovery_mode;
} state_context_t;

State Manager Implementation

static state_context_t state_ctx;
static state_handler_t state_handlers[MAX_STATE_HANDLERS];

typedef struct {
    system_state_t from_state;
    system_state_t to_state;
    bool (*condition)(void);
    void (*transition_handler)(void);
} state_transition_t;

static state_transition_t state_transitions[MAX_STATE_TRANSITIONS];

int transition_state(system_state_t new_state) {
    uint32_t current_time = get_system_time();
    
    // Check if transition is allowed
    for (int i = 0; i < MAX_STATE_TRANSITIONS; i++) {
        if (state_transitions[i].from_state == state_ctx.current &&
            state_transitions[i].to_state == new_state) {
            
            // Check transition condition if present
            if (state_transitions[i].condition && 
                !state_transitions[i].condition()) {
                return -1;
            }
            
            // Execute transition handler if present
            if (state_transitions[i].transition_handler) {
                state_transitions[i].transition_handler();
            }
            
            // Update state context
            state_ctx.previous = state_ctx.current;
            state_ctx.current = new_state;
            state_ctx.state_duration = 
                current_time - state_ctx.state_entry_time;
            state_ctx.state_entry_time = current_time;
            
            // Execute new state handler
            if (state_handlers[new_state]) {
                state_handlers[new_state]();
            }
            
            return 0;
        }
    }
    
    return -1;  // Invalid transition
}

State Handler Registration

void register_state_handlers(void) {
    // Register core state handlers
    state_handlers[SYSTEM_STATE_RESET] = handle_reset_state;
    state_handlers[SYSTEM_STATE_EARLY_INIT] = handle_early_init;
    state_handlers[SYSTEM_STATE_HW_DETECT] = handle_hardware_detection;
    state_handlers[SYSTEM_STATE_MEMORY_INIT] = handle_memory_init;
    state_handlers[SYSTEM_STATE_DEVICE_INIT] = handle_device_init;
    
    // Register allowed state transitions
    register_transition(SYSTEM_STATE_RESET, SYSTEM_STATE_EARLY_INIT, NULL);
    register_transition(SYSTEM_STATE_EARLY_INIT, SYSTEM_STATE_HW_DETECT, 
                       check_early_init_complete);
    register_transition(SYSTEM_STATE_HW_DETECT, SYSTEM_STATE_MEMORY_INIT,
                       check_hardware_ready);
}

Magic-1 Bootloader Technical Analysis - Part 33: Boot Media Management

Boot Media Interface Layer

The boot media management system provides a uniform interface for accessing different boot storage devices.

Core Boot Media Interface

#define MAX_BOOT_DEVICES 4
#define SECTOR_SIZE 512
#define MAX_RETRIES 3

typedef enum {
    BOOT_MEDIA_IDE,
    BOOT_MEDIA_CF,
    BOOT_MEDIA_ROM,
    BOOT_MEDIA_NET
} boot_media_type_t;

typedef struct {
    boot_media_type_t type;
    uint8_t  id;
    uint32_t sector_count;
    bool     bootable;
    char     description[32];
    
    /* Device operations */
    int (*init)(void);
    int (*read_sectors)(uint32_t start, uint32_t count, void* buffer);
    int (*write_sectors)(uint32_t start, uint32_t count, const void* buffer);
    void (*shutdown)(void);
} boot_device_t;

Boot Media Manager Implementation

static struct {
    boot_device_t* devices[MAX_BOOT_DEVICES];
    uint8_t device_count;
    boot_device_t* active_device;
} boot_media_ctx;

int register_boot_device(boot_device_t* device) {
    if (boot_media_ctx.device_count >= MAX_BOOT_DEVICES) {
        return -1;
    }
    
    if (device->init && device->init() != 0) {
        return -2;
    }
    
    boot_media_ctx.devices[boot_media_ctx.device_count++] = device;
    
    // If this is the first bootable device, make it active
    if (device->bootable && !boot_media_ctx.active_device) {
        boot_media_ctx.active_device = device;
    }
    
    return 0;
}

Boot Media Error Handling

typedef struct {
    uint32_t sector;
    uint32_t retry_count;
    uint32_t last_error;
    uint32_t timestamp;
} media_error_info_t;

int handle_media_error(boot_device_t* device, uint32_t sector, uint32_t error) {
    static media_error_info_t error_info;
    
    error_info.sector = sector;
    error_info.last_error = error;
    error_info.timestamp = get_system_time();
    
    if (++error_info.retry_count > MAX_RETRIES) {
        // Log critical error
        log_critical("Boot media error: device=%d sector=%d error=0x%x",
                    device->id, sector, error);
        return -1;
    }
    
    // Attempt recovery
    switch (error) {
        case ERR_TIMEOUT:
            delay_ms(100 * error_info.retry_count);
            break;
        case ERR_CRC:
            // Reset device controller
            if (device->init) {
                device->init();
            }
            break;
    }
    
    return 0;  // Retry operation
}

Magic-1 Bootloader Technical Analysis - Part 34: System Log Management

System Logging Architecture

The logging system provides centralized logging capabilities with different severity levels and output targets.

Core Logging Interface

#define MAX_LOG_ENTRIES 256 
#define MAX_LOG_MSG_LEN 128
#define LOG_SIGNATURE  0x4C4F4721  // "LOG!"

typedef enum {
    LOG_LEVEL_DEBUG = 0,
    LOG_LEVEL_INFO,
    LOG_LEVEL_WARN,
    LOG_LEVEL_ERROR,
    LOG_LEVEL_FATAL
} log_level_t;

typedef struct {
    uint32_t timestamp;
    log_level_t level;
    char message[MAX_LOG_MSG_LEN];
    uint16_t source_line;
    const char* source_file;
} log_entry_t;

Circular Log Buffer Implementation

struct log_buffer {
    log_entry_t entries[MAX_LOG_ENTRIES];
    uint16_t head;
    uint16_t tail;
    uint32_t total_entries;
    uint32_t dropped_entries;
    bool overflow;
};

static struct log_buffer log_ctx;

void log_message(log_level_t level, const char* file, int line, const char* fmt, ...) {
    va_list args;
    log_entry_t* entry;
    
    // Check if buffer is full
    if (((log_ctx.head + 1) % MAX_LOG_ENTRIES) == log_ctx.tail) {
        log_ctx.dropped_entries++;
        log_ctx.overflow = true;
        
        // Move tail to make room
        log_ctx.tail = (log_ctx.tail + 1) % MAX_LOG_ENTRIES;
    }
    
    entry = &log_ctx.entries[log_ctx.head];
    entry->timestamp = get_system_time();
    entry->level = level;
    entry->source_line = line;
    entry->source_file = file;
    
    va_start(args, fmt);
    vsnprintf(entry->message, MAX_LOG_MSG_LEN, fmt, args);
    va_end(args);
    
    log_ctx.head = (log_ctx.head + 1) % MAX_LOG_ENTRIES;
    log_ctx.total_entries++;
    
    // Output to debug console if enabled
    if (is_debug_console_enabled()) {
        output_to_debug_console(entry);
    }
}

Log Persistence Layer

#define LOG_SECTOR_START 0x1F000
#define LOG_SECTORS_COUNT 8

int save_log_to_storage(void) {
    uint8_t buffer[SECTOR_SIZE];
    uint32_t current_sector = LOG_SECTOR_START;
    uint16_t entries_per_sector = SECTOR_SIZE / sizeof(log_entry_t);
    uint16_t current_entry = log_ctx.tail;
    
    while (current_entry != log_ctx.head) {
        uint16_t count = 0;
        uint8_t* ptr = buffer;
        
        // Fill sector buffer
        while (count < entries_per_sector && current_entry != log_ctx.head) {
            memcpy(ptr, &log_ctx.entries[current_entry], sizeof(log_entry_t));
            ptr += sizeof(log_entry_t);
            current_entry = (current_entry + 1) % MAX_LOG_ENTRIES;
            count++;
        }
        
        // Write sector
        if (write_sector(current_sector++, buffer) != 0) {
            return -1;
        }
    }
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 35: Task Scheduler Implementation

The bootloader implements a simple task scheduler to manage initialization and background tasks during the boot process.

Task Scheduler Core Components

Task Structure Definition

#define MAX_TASKS 16
#define MAX_TASK_NAME 32
#define TASK_STACK_SIZE 256

typedef enum {
    TASK_STATE_IDLE,
    TASK_STATE_READY,
    TASK_STATE_RUNNING,
    TASK_STATE_BLOCKED,
    TASK_STATE_SUSPENDED
} task_state_t;

typedef struct task {
    char name[MAX_TASK_NAME];
    task_state_t state;
    uint8_t priority;
    void (*entry_point)(void);
    uint8_t stack[TASK_STACK_SIZE];
    uint16_t stack_pointer;
    uint32_t run_count;
    uint32_t last_run;
    struct task *next;
} task_t;

Scheduler Implementation

static struct {
    task_t tasks[MAX_TASKS];
    task_t *current_task;
    task_t *idle_task;
    uint8_t task_count;
    uint32_t tick_count;
    bool scheduling_enabled;
} scheduler_ctx;

task_t *create_task(const char *name, void (*entry)(void), uint8_t priority) {
    if (scheduler_ctx.task_count >= MAX_TASKS) {
        return NULL;
    }

    task_t *task = &scheduler_ctx.tasks[scheduler_ctx.task_count++];
    strncpy(task->name, name, MAX_TASK_NAME - 1);
    task->state = TASK_STATE_READY;
    task->priority = priority;
    task->entry_point = entry;
    task->stack_pointer = TASK_STACK_SIZE - 1;
    task->run_count = 0;
    task->last_run = 0;

    // Initialize task stack
    task->stack[task->stack_pointer--] = (uint16_t)entry & 0xFF;
    task->stack[task->stack_pointer--] = (uint16_t)entry >> 8;
    task->stack[task->stack_pointer] = 0x00;  // Initial status register

    return task;
}

void schedule(void) {
    task_t *next_task = NULL;
    uint8_t highest_priority = 0xFF;

    // Find highest priority ready task
    for (int i = 0; i < scheduler_ctx.task_count; i++) {
        task_t *task = &scheduler_ctx.tasks[i];
        if (task->state == TASK_STATE_READY && 
            task->priority < highest_priority) {
            highest_priority = task->priority;
            next_task = task;
        }
    }

    if (!next_task) {
        next_task = scheduler_ctx.idle_task;
    }

    if (next_task != scheduler_ctx.current_task) {
        task_switch(next_task);
    }
}

Magic-1 Bootloader Technical Analysis - Part 36: Boot Progress Monitoring

The boot progress monitoring system tracks and reports the status of the boot sequence, providing feedback through various output channels.

Boot Progress Manager

Core Progress Tracking Structures

#define MAX_PROGRESS_STAGES 16
#define MAX_STAGE_DESC 64

typedef enum {
    PROGRESS_NONE,
    PROGRESS_STARTED,
    PROGRESS_COMPLETED,
    PROGRESS_FAILED,
    PROGRESS_SKIPPED
} progress_state_t;

typedef struct {
    char description[MAX_STAGE_DESC];
    uint8_t percent;
    uint32_t start_time;
    uint32_t duration;
    progress_state_t state;
} boot_stage_t;

Progress Manager Implementation

static struct {
    boot_stage_t stages[MAX_PROGRESS_STAGES];
    uint8_t current_stage;
    uint8_t total_stages;
    uint32_t boot_start_time;
    bool verbose_output;
} progress_ctx;

void init_boot_progress(void) {
    memset(&progress_ctx, 0, sizeof(progress_ctx));
    progress_ctx.boot_start_time = get_system_time();
    
    // Register default boot stages
    register_boot_stage("Hardware Detection", 10);
    register_boot_stage("Memory Initialization", 20);
    register_boot_stage("Device Initialization", 40);
    register_boot_stage("Boot Image Loading", 70);
    register_boot_stage("System Startup", 100);
}

void update_boot_progress(uint8_t stage, progress_state_t state) {
    if (stage >= progress_ctx.total_stages) {
        return;
    }
    
    boot_stage_t* current = &progress_ctx.stages[stage];
    current->state = state;
    
    if (state == PROGRESS_STARTED) {
        current->start_time = get_system_time();
    } else if (state == PROGRESS_COMPLETED || state == PROGRESS_FAILED) {
        current->duration = get_system_time() - current->start_time;
    }
    
    display_progress();
}

Progress Display Implementation

void display_progress(void) {
    const char* state_chars = "-+*!S";  // None, Started, Completed, Failed, Skipped
    
    printf("\rBoot Progress: [");
    
    for (int i = 0; i < progress_ctx.total_stages; i++) {
        printf("%c", state_chars[progress_ctx.stages[i].state]);
    }
    
    printf("] %d%%", progress_ctx.stages[progress_ctx.current_stage].percent);
    
    if (progress_ctx.verbose_output) {
        printf("\n%s: %s", 
               progress_ctx.stages[progress_ctx.current_stage].description,
               progress_ctx.stages[progress_ctx.current_stage].state == PROGRESS_FAILED ?
               "FAILED" : "OK");
    }
}

Magic-1 Bootloader Technical Analysis - Part 37: Hardware Abstraction Layer Extensions

The HAL extensions provide additional hardware support and abstraction layers for specialized peripherals.

Extended HAL Components

DMA Controller Interface

#define DMA_MAX_CHANNELS 4
#define DMA_BUFFER_SIZE 2048

typedef enum {
    DMA_DIR_MEM_TO_MEM,
    DMA_DIR_MEM_TO_DEV,
    DMA_DIR_DEV_TO_MEM
} dma_direction_t;

struct dma_transfer {
    void* src_addr;
    void* dst_addr;
    uint32_t size;
    dma_direction_t direction;
    void (*callback)(void* context);
    void* context;
};

DMA Controller Implementation

static struct {
    struct dma_transfer active_transfers[DMA_MAX_CHANNELS];
    uint8_t channel_mask;
    uint32_t transfer_count;
} dma_ctx;

int hal_dma_start_transfer(uint8_t channel, struct dma_transfer* transfer) {
    if (channel >= DMA_MAX_CHANNELS || (dma_ctx.channel_mask & (1 << channel))) {
        return -1;
    }
    
    // Configure DMA hardware registers
    uint16_t control = DMA_ENABLE;
    if (transfer->direction == DMA_DIR_MEM_TO_DEV) {
        control |= DMA_MEM_TO_DEV;
    } else if (transfer->direction == DMA_DIR_DEV_TO_MEM) {
        control |= DMA_DEV_TO_MEM;
    }
    
    outw(DMA_BASE + (channel * 8) + DMA_CONTROL, control);
    outl(DMA_BASE + (channel * 8) + DMA_SRC_ADDR, (uint32_t)transfer->src_addr);
    outl(DMA_BASE + (channel * 8) + DMA_DST_ADDR, (uint32_t)transfer->dst_addr);
    outw(DMA_BASE + (channel * 8) + DMA_COUNT, transfer->size);
    
    // Store transfer info
    memcpy(&dma_ctx.active_transfers[channel], transfer, sizeof(struct dma_transfer));
    dma_ctx.channel_mask |= (1 << channel);
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 38: Runtime Service Implementation

Runtime Services Architecture

The runtime services provide essential functions that can be called during boot and passed to the loaded operating system.

Core Runtime Service Interface

#define MAX_SERVICES 16
#define SERVICE_NAME_MAX 32

typedef enum {
    SVC_MEMORY,
    SVC_CONSOLE,
    SVC_STORAGE,
    SVC_TIME,
    SVC_CONFIG
} service_type_t;

typedef struct runtime_service {
    char name[SERVICE_NAME_MAX];
    service_type_t type;
    uint32_t version;
    void* interface;
    bool (*init)(void);
    void (*shutdown)(void);
} runtime_service_t;

Service Manager Implementation

static struct {
    runtime_service_t services[MAX_SERVICES];
    uint8_t service_count;
    bool initialized;
} service_ctx;

int register_runtime_service(runtime_service_t* service) {
    if (service_ctx.service_count >= MAX_SERVICES) {
        return -1;
    }
    
    // Initialize service if needed
    if (service->init && !service->init()) {
        return -2;
    }
    
    // Add to service registry
    memcpy(&service_ctx.services[service_ctx.service_count],
           service, sizeof(runtime_service_t));
    service_ctx.service_count++;
    
    return 0;
}

void* get_service_interface(service_type_t type) {
    for (int i = 0; i < service_ctx.service_count; i++) {
        if (service_ctx.services[i].type == type) {
            return service_ctx.services[i].interface;
        }
    }
    return NULL;
}

Magic-1 Bootloader Technical Analysis - Part 39: Boot Parameter Passing

Boot Parameter System

The bootloader needs to pass various parameters and configuration data to the loaded operating system in a structured way.

Core Parameter Structure

#define BOOT_PARAM_MAGIC     0x4D314250  // "M1BP"
#define MAX_MEMORY_REGIONS   16
#define MAX_BOOT_MODULES     8
#define MAX_CMDLINE_LENGTH   256

/* Memory region descriptor */
struct memory_region {
    uint32_t start;
    uint32_t size;
    uint32_t flags;
    uint32_t type;
};

/* Boot module information */
struct boot_module {
    uint32_t start;
    uint32_t size;
    char     name[32];
    uint32_t flags;
};

/* Main boot parameter block */
struct boot_params {
    uint32_t magic;
    uint32_t version;
    uint32_t total_size;
    
    /* Memory map */
    uint32_t num_memory_regions;
    struct memory_region memory_map[MAX_MEMORY_REGIONS];
    
    /* Boot modules */
    uint32_t num_modules;
    struct boot_module modules[MAX_BOOT_MODULES];
    
    /* Command line */
    char cmdline[MAX_CMDLINE_LENGTH];
    
    /* Video information */
    uint16_t video_cols;
    uint16_t video_rows;
    uint32_t framebuffer_addr;
    
    /* Runtime services */
    uint32_t runtime_services_ptr;
    
    /* Boot device info */
    uint8_t  boot_device_type;
    uint8_t  boot_device_id;
    uint16_t boot_partition;
    
    /* Checksum */
    uint32_t checksum;
};

Parameter Management Implementation

static struct boot_params boot_params;

void init_boot_params(void) {
    memset(&boot_params, 0, sizeof(struct boot_params));
    boot_params.magic = BOOT_PARAM_MAGIC;
    boot_params.version = 0x0100;  // Version 1.0
    boot_params.total_size = sizeof(struct boot_params);
}

int add_memory_region(uint32_t start, uint32_t size, uint32_t type, uint32_t flags) {
    if (boot_params.num_memory_regions >= MAX_MEMORY_REGIONS) {
        return -1;
    }
    
    struct memory_region* region = 
        &boot_params.memory_map[boot_params.num_memory_regions++];
        
    region->start = start;
    region->size = size;
    region->type = type;
    region->flags = flags;
    
    return 0;
}

void update_checksum(void) {
    uint32_t* ptr = (uint32_t*)&boot_params;
    uint32_t checksum = 0;
    int count = (sizeof(struct boot_params) - sizeof(uint32_t)) / 4;
    
    while (count--) {
        checksum += *ptr++;
    }
    
    boot_params.checksum = ~checksum + 1;  // Two's complement
}

Magic-1 Bootloader Technical Analysis - Part 40: Boot Image Compression Support

Compression System Architecture

The bootloader implements a compression framework to reduce boot image size and improve load times.

Core Compression Interface

#define COMPRESS_MAGIC   0x4D31435A  // "M1CZ"
#define MAX_CHUNK_SIZE   4096
#define MIN_CHUNK_SIZE   512

typedef enum {
    COMPRESS_NONE = 0,
    COMPRESS_RLE,
    COMPRESS_LZ,
    COMPRESS_HUFFMAN
} compression_type_t;

struct compressed_header {
    uint32_t magic;
    uint16_t version;
    uint16_t type;
    uint32_t original_size;
    uint32_t compressed_size;
    uint32_t chunk_size;
    uint32_t num_chunks;
    uint32_t checksum;
};

Compression Manager Implementation

struct chunk_info {
    uint32_t offset;
    uint32_t comp_size;
    uint32_t orig_size;
    uint32_t checksum;
};

static uint8_t work_buffer[MAX_CHUNK_SIZE];

int decompress_boot_image(const uint8_t* src, uint8_t* dst, uint32_t* size) {
    struct compressed_header* header = (struct compressed_header*)src;
    struct chunk_info* chunks;
    uint32_t offset = 0;
    
    // Validate header
    if (header->magic != COMPRESS_MAGIC) {
        return -1;
    }
    
    // Get chunk table
    chunks = (struct chunk_info*)(src + sizeof(struct compressed_header));
    
    // Process each chunk
    for (uint32_t i = 0; i < header->num_chunks; i++) {
        int status;
        
        switch (header->type) {
            case COMPRESS_RLE:
                status = decompress_rle(
                    src + chunks[i].offset,
                    chunks[i].comp_size,
                    dst + offset,
                    chunks[i].orig_size
                );
                break;
                
            case COMPRESS_LZ:
                status = decompress_lz(
                    src + chunks[i].offset,
                    chunks[i].comp_size,
                    dst + offset,
                    chunks[i].orig_size
                );
                break;
                
            default:
                return -2;
        }
        
        if (status != 0) {
            return status;
        }
        
        offset += chunks[i].orig_size;
    }
    
    *size = header->original_size;
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 41: Boot Security Implementation

Security Framework

The bootloader implements security measures to ensure system integrity and prevent unauthorized modifications.

Core Security Structures

#define SECURITY_VERSION 0x0100
#define HASH_SIZE       32
#define SIG_SIZE       64
#define KEY_SIZE       32

typedef enum {
    SEC_LEVEL_NONE,
    SEC_LEVEL_BASIC,
    SEC_LEVEL_SECURE,
    SEC_LEVEL_MAX
} security_level_t;

struct security_header {
    uint16_t version;
    uint16_t level;
    uint8_t  hash[HASH_SIZE];
    uint8_t  signature[SIG_SIZE];
    uint32_t flags;
    uint32_t timestamp;
};

Security Manager Implementation

static struct {
    security_level_t current_level;
    uint8_t public_key[KEY_SIZE];
    bool secure_boot_enabled;
    uint32_t boot_count;
} security_ctx;

int verify_boot_image(const uint8_t* image_data, size_t size) {
    struct security_header* header;
    uint8_t computed_hash[HASH_SIZE];
    
    if (size < sizeof(struct security_header)) {
        return -1;
    }
    
    header = (struct security_header*)image_data;
    
    // Verify version compatibility
    if (header->version > SECURITY_VERSION) {
        return -2;
    }
    
    // Calculate image hash
    sha256_calculate(image_data + sizeof(struct security_header),
                    size - sizeof(struct security_header),
                    computed_hash);
                    
    // Compare hashes
    if (memcmp(computed_hash, header->hash, HASH_SIZE) != 0) {
        return -3;
    }
    
    // Verify signature if secure boot enabled
    if (security_ctx.secure_boot_enabled) {
        if (!verify_signature(computed_hash, 
                            header->signature,
                            security_ctx.public_key)) {
            return -4;
        }
    }
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 42: Boot Network Support

The network boot support allows loading boot images and configuration over the network interface.

Core Network Boot Interface

#define NET_BOOT_PORT    69
#define MAX_PACKET_SIZE  1024
#define MAX_RETRIES     3
#define TIMEOUT_MS      1000

typedef enum {
    NET_PROTO_TFTP,
    NET_PROTO_HTTP,
    NET_PROTO_CUSTOM
} net_protocol_t;

struct net_boot_config {
    uint32_t server_ip;
    uint16_t server_port;
    net_protocol_t protocol;
    char boot_file[128];
    uint32_t timeout_ms;
};

Network Boot Implementation

static struct {
    struct net_boot_config config;
    uint8_t mac_addr[6];
    uint32_t ip_addr;
    bool link_up;
    uint32_t bytes_received;
} net_ctx;

int init_network_boot(void) {
    // Initialize network hardware
    if (init_network_hardware() != 0) {
        return -1;
    }
    
    // Wait for link
    uint32_t timeout = 5000;  // 5 seconds
    while (!net_ctx.link_up && timeout > 0) {
        check_link_status();
        delay_ms(100);
        timeout -= 100;
    }
    
    if (!net_ctx.link_up) {
        return -2;
    }
    
    // Get network config via DHCP
    if (get_network_config() != 0) {
        return -3;
    }
    
    return 0;
}

TFTP Boot Protocol Handler

#define TFTP_RRQ   1
#define TFTP_DATA  3
#define TFTP_ACK   4
#define TFTP_ERROR 5

struct tftp_packet {
    uint16_t opcode;
    union {
        uint16_t block_num;
        uint16_t error_code;
    };
    uint8_t data[512];
};

int download_boot_image_tftp(const char* filename, void* buffer, size_t* size) {
    struct tftp_packet packet;
    uint16_t block = 1;
    size_t total = 0;
    
    // Send initial RRQ
    packet.opcode = htons(TFTP_RRQ);
    strcpy((char*)packet.data, filename);
    send_udp(net_ctx.config.server_ip, NET_BOOT_PORT, &packet, 
             strlen(filename) + 3);
             
    // Receive data blocks
    while (1) {
        size_t received = receive_udp(&packet, sizeof(packet));
        if (received < 4) continue;
        
        switch (ntohs(packet.opcode)) {
            case TFTP_DATA:
                if (ntohs(packet.block_num) == block) {
                    memcpy(buffer + total, packet.data, received - 4);
                    total += received - 4;
                    send_tftp_ack(block++);
                }
                break;
                
            case TFTP_ERROR:
                return -1;
        }
        
        if (received < 516) break;  // Last packet
    }
    
    *size = total;
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 43: Boot Time Optimization

Core Optimization Framework

The bootloader implements various optimizations to reduce boot time and improve performance.

Boot Time Profiler Interface

#define MAX_PROFILE_POINTS 32
#define PROFILE_NAME_LEN   32

typedef struct {
    char name[PROFILE_NAME_LEN];
    uint32_t start_time;
    uint32_t duration;
    uint32_t calls;
    bool active;
} profile_point_t;

struct boot_profile {
    profile_point_t points[MAX_PROFILE_POINTS];
    uint8_t point_count;
    uint32_t total_boot_time;
    uint32_t boot_start_time;
};

Profile Manager Implementation

static struct boot_profile profile_ctx;

void profile_start_point(const char* name) {
    for (int i = 0; i < profile_ctx.point_count; i++) {
        if (strcmp(profile_ctx.points[i].name, name) == 0) {
            if (!profile_ctx.points[i].active) {
                profile_ctx.points[i].start_time = get_system_time();
                profile_ctx.points[i].active = true;
                profile_ctx.points[i].calls++;
            }
            return;
        }
    }
    
    // New profile point
    if (profile_ctx.point_count < MAX_PROFILE_POINTS) {
        profile_point_t* point = &profile_ctx.points[profile_ctx.point_count++];
        strncpy(point->name, name, PROFILE_NAME_LEN - 1);
        point->start_time = get_system_time();
        point->active = true;
        point->calls = 1;
    }
}

void profile_end_point(const char* name) {
    uint32_t end_time = get_system_time();
    
    for (int i = 0; i < profile_ctx.point_count; i++) {
        if (strcmp(profile_ctx.points[i].name, name) == 0) {
            if (profile_ctx.points[i].active) {
                profile_ctx.points[i].duration += 
                    end_time - profile_ctx.points[i].start_time;
                profile_ctx.points[i].active = false;
            }
            break;
        }
    }
}

void print_profile_report(void) {
    printf("\nBoot Profile Report\n");
    printf("==================\n");
    printf("Total Boot Time: %d ms\n\n", 
           get_system_time() - profile_ctx.boot_start_time);
    printf("%-20s %10s %10s %10s\n", "Phase", "Calls", "Time(ms)", "%Total");
    printf("-------------------------------------------------\n");
    
    for (int i = 0; i < profile_ctx.point_count; i++) {
        float percent = (profile_ctx.points[i].duration * 100.0f) / 
                       profile_ctx.total_boot_time;
        printf("%-20s %10d %10d %10.1f\n",
               profile_ctx.points[i].name,
               profile_ctx.points[i].calls,
               profile_ctx.points[i].duration,
               percent);
    }
}

Magic-1 Bootloader Technical Analysis - Part 44: Boot Configuration Management

The configuration management system provides a flexible way to manage boot-time settings and parameters.

Core Configuration Manager

Configuration Structures

#define MAX_CONFIG_ENTRIES 64
#define MAX_KEY_LENGTH    32
#define MAX_VALUE_LENGTH  128

typedef enum {
    CONFIG_TYPE_STRING,
    CONFIG_TYPE_INTEGER,
    CONFIG_TYPE_BOOLEAN,
    CONFIG_TYPE_ARRAY
} config_type_t;

typedef struct {
    char key[MAX_KEY_LENGTH];
    config_type_t type;
    union {
        char str_value[MAX_VALUE_LENGTH];
        int64_t int_value;
        bool bool_value;
        struct {
            void* data;
            size_t length;
        } array;
    };
} config_entry_t;

Configuration Manager Implementation

static struct {
    config_entry_t entries[MAX_CONFIG_ENTRIES];
    uint16_t entry_count;
    bool modified;
    char config_file[256];
} config_ctx;

int load_boot_config(const char* filename) {
    FILE* fp = fopen(filename, "r");
    if (!fp) {
        return -1;
    }

    char line[256];
    while (fgets(line, sizeof(line), fp)) {
        char key[MAX_KEY_LENGTH];
        char value[MAX_VALUE_LENGTH];
        
        // Skip comments and empty lines
        if (line[0] == '#' || line[0] == '\n') {
            continue;
        }
        
        if (sscanf(line, "%31[^=]=%127[^\n]", key, value) == 2) {
            // Trim whitespace
            trim_string(key);
            trim_string(value);
            
            // Store configuration
            set_config_value(key, value);
        }
    }
    
    fclose(fp);
    strncpy(config_ctx.config_file, filename, sizeof(config_ctx.config_file) - 1);
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 45: Boot Menu Implementation

The boot menu provides an interactive interface for selecting boot options and configuring system parameters.

Boot Menu Core Components

Menu Structure Definition

#define MAX_MENU_ITEMS 16
#define MAX_ITEM_TEXT  64
#define MAX_MENU_DEPTH 4

typedef enum {
    MENU_ACTION_BOOT,
    MENU_ACTION_SUBMENU,
    MENU_ACTION_COMMAND,
    MENU_ACTION_EXIT
} menu_action_t;

typedef struct menu_item {
    char text[MAX_ITEM_TEXT];
    menu_action_t action;
    union {
        struct {
            char image_name[32];
            char parameters[64];
        } boot;
        struct menu* submenu;
        void (*command)(void);
    };
    bool enabled;
} menu_item_t;

typedef struct menu {
    char title[MAX_ITEM_TEXT];
    menu_item_t items[MAX_MENU_ITEMS];
    uint8_t item_count;
    struct menu* parent;
} menu_t;

Menu Manager Implementation

static struct {
    menu_t* current_menu;
    menu_t* root_menu;
    uint8_t timeout;
    bool timeout_enabled;
    uint32_t last_input;
} menu_ctx;

void display_menu(menu_t* menu) {
    clear_screen();
    printf("\n%s\n", menu->title);
    printf("==================\n\n");
    
    for (int i = 0; i < menu->item_count; i++) {
        if (menu->items[i].enabled) {
            printf("%d. %s\n", i + 1, menu->items[i].text);
        } else {
            printf("   %s (Disabled)\n", menu->items[i].text);
        }
    }
    
    if (menu->parent) {
        printf("\n0. Back\n");
    }
    
    if (menu_ctx.timeout_enabled) {
        printf("\nAutoboot in %d seconds...\n", menu_ctx.timeout);
    }
    
    printf("\nSelect option: ");
}

int handle_menu_input(char input) {
    int selection = input - '0';
    menu_item_t* item;
    
    if (selection < 0 || selection > menu_ctx.current_menu->item_count) {
        return -1;
    }
    
    if (selection == 0 && menu_ctx.current_menu->parent) {
        menu_ctx.current_menu = menu_ctx.current_menu->parent;
        return 0;
    }
    
    item = &menu_ctx.current_menu->items[selection - 1];
    if (!item->enabled) {
        return -1;
    }
    
    switch (item->action) {
        case MENU_ACTION_BOOT:
            return boot_system(item->boot.image_name, item->boot.parameters);
            
        case MENU_ACTION_SUBMENU:
            menu_ctx.current_menu = item->submenu;
            break;
            
        case MENU_ACTION_COMMAND:
            item->command();
            break;
            
        case MENU_ACTION_EXIT:
            return 1;
    }
    
    return 0;
}

Type 'next' for Part 46 covering Boot Process State Machine.

Magic-1 Bootloader Technical Analysis - Part 46: Boot Process State Machine

The boot process state machine manages the sequence of operations required to initialize the system and load the operating system.

State Machine Core

State Definitions

typedef enum {
    BOOT_STATE_RESET,
    BOOT_STATE_EARLY_INIT,
    BOOT_STATE_HARDWARE_INIT,
    BOOT_STATE_MEMORY_INIT,
    BOOT_STATE_DEVICE_INIT,
    BOOT_STATE_LOAD_CONFIG,
    BOOT_STATE_MENU,
    BOOT_STATE_LOAD_IMAGE,
    BOOT_STATE_PREPARE_EXIT,
    BOOT_STATE_EXIT,
    BOOT_STATE_ERROR
} boot_state_t;

typedef struct {
    boot_state_t current;
    boot_state_t previous;
    uint32_t entry_time;
    uint32_t timeout;
    char error_message[128];
    bool menu_enabled;
    bool timeout_enabled;
} boot_context_t;

State Machine Implementation

static boot_context_t boot_ctx;

static const struct {
    boot_state_t state;
    const char* name;
    int (*handler)(void);
    uint32_t timeout;  // Maximum time in ms
} state_table[] = {
    { BOOT_STATE_RESET,       "System Reset",      handle_reset,       1000 },
    { BOOT_STATE_EARLY_INIT,  "Early Init",        handle_early_init,  2000 },
    { BOOT_STATE_HARDWARE_INIT, "Hardware Init",   handle_hw_init,     5000 },
    { BOOT_STATE_MEMORY_INIT, "Memory Init",       handle_mem_init,    3000 },
    { BOOT_STATE_DEVICE_INIT, "Device Init",       handle_dev_init,    4000 },
    { BOOT_STATE_LOAD_CONFIG, "Load Config",       handle_config,      2000 },
    { BOOT_STATE_MENU,        "Boot Menu",         handle_menu,        30000},
    { BOOT_STATE_LOAD_IMAGE,  "Load Image",        handle_load_image,  5000 },
    { BOOT_STATE_PREPARE_EXIT,"Prepare Exit",      handle_prep_exit,   1000 },
    { BOOT_STATE_EXIT,        "Exit Boot",         handle_exit,        1000 },
    { BOOT_STATE_ERROR,       "Error",             handle_error,       0    },
    { 0, NULL, NULL, 0 }
};

int execute_boot_sequence(void) {
    int status;
    uint32_t current_time;
    
    boot_ctx.current = BOOT_STATE_RESET;
    boot_ctx.entry_time = get_system_time();
    
    while (1) {
        current_time = get_system_time();
        
        // Execute current state handler
        for (int i = 0; state_table[i].handler != NULL; i++) {
            if (state_table[i].state == boot_ctx.current) {
                // Check for timeout
                if (state_table[i].timeout > 0 &&
                    (current_time - boot_ctx.entry_time) > state_table[i].timeout) {
                    sprintf(boot_ctx.error_message, "Timeout in state %s",
                            state_table[i].name);
                    boot_ctx.current = BOOT_STATE_ERROR;
                    break;
                }
                
                status = state_table[i].handler();
                if (status != 0) {
                    boot_ctx.current = BOOT_STATE_ERROR;
                }
                break;
            }
        }
        
        if (boot_ctx.current == BOOT_STATE_EXIT) {
            return 0;
        } else if (boot_ctx.current == BOOT_STATE_ERROR) {
            return -1;
        }
    }
}

Magic-1 Bootloader Technical Analysis - Part 47: Boot Storage Management

The boot storage management system provides a unified interface for accessing different storage devices and file systems during the boot process.

Core Storage Interface

#define MAX_STORAGE_DEVICES 4
#define SECTOR_SIZE 512
#define MAX_RETRIES 3

typedef enum {
    STORAGE_TYPE_IDE,
    STORAGE_TYPE_FLASH,
    STORAGE_TYPE_MMC,
    STORAGE_TYPE_NET
} storage_type_t;

typedef struct storage_device {
    storage_type_t type;
    uint8_t id;
    uint32_t sector_count;
    bool bootable;
    char name[32];
    
    /* Device operations */
    int (*init)(struct storage_device* dev);
    int (*read_sectors)(struct storage_device* dev, uint32_t start, 
                       uint32_t count, void* buffer);
    int (*write_sectors)(struct storage_device* dev, uint32_t start, 
                        uint32_t count, const void* buffer);
    void (*shutdown)(struct storage_device* dev);
} storage_device_t;

Storage Manager Implementation

static struct {
    storage_device_t* devices[MAX_STORAGE_DEVICES];
    uint8_t device_count;
    storage_device_t* boot_device;
} storage_ctx;

int register_storage_device(storage_device_t* device) {
    if (storage_ctx.device_count >= MAX_STORAGE_DEVICES) {
        return -1;
    }
    
    // Initialize device
    if (device->init && device->init(device) != 0) {
        return -2;
    }
    
    storage_ctx.devices[storage_ctx.device_count++] = device;
    
    // Update boot device if this is bootable
    if (device->bootable && !storage_ctx.boot_device) {
        storage_ctx.boot_device = device;
    }
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 48: Boot Progress Reporting

The boot progress reporting system provides feedback about the boot sequence status through various output channels.

Progress Reporting Core

First, let's define our progress reporting structures:

#define MAX_PROGRESS_STAGES 16
#define MAX_STAGE_NAME 32
#define MAX_STATUS_MSG 64

typedef enum {
    PROGRESS_PENDING,
    PROGRESS_RUNNING,
    PROGRESS_SUCCESS,
    PROGRESS_FAILED,
    PROGRESS_SKIPPED
} progress_state_t;

typedef struct {
    char name[MAX_STAGE_NAME];
    uint8_t percent;
    progress_state_t state;
    uint32_t start_time;
    uint32_t duration;
    char status[MAX_STATUS_MSG];
} progress_stage_t;

typedef struct {
    progress_stage_t stages[MAX_PROGRESS_STAGES];
    uint8_t current_stage;
    uint8_t total_stages;
    uint32_t boot_start_time;
    bool verbose_mode;
} progress_context_t;

Here's the core progress manager implementation:

static progress_context_t progress_ctx;

void init_progress_manager(void) {
    memset(&progress_ctx, 0, sizeof(progress_context_t));
    progress_ctx.boot_start_time = get_system_time();
    progress_ctx.verbose_mode = true;
    
    // Register default boot stages
    register_boot_stage("Hardware Detection", 0);
    register_boot_stage("Memory Initialization", 20);
    register_boot_stage("Device Initialization", 40);
    register_boot_stage("Configuration Loading", 60);
    register_boot_stage("Boot Image Loading", 80);
    register_boot_stage("System Startup", 100);
}

void update_boot_progress(uint8_t stage, progress_state_t state, const char* msg) {
    if (stage >= progress_ctx.total_stages) {
        return;
    }
    
    progress_stage_t* current = &progress_ctx.stages[stage];
    current->state = state;
    
    if (msg) {
        strncpy(current->status, msg, MAX_STATUS_MSG - 1);
    }
    
    if (state == PROGRESS_RUNNING) {
        current->start_time = get_system_time();
    } else if (state == PROGRESS_SUCCESS || state == PROGRESS_FAILED) {
        current->duration = get_system_time() - current->start_time;
    }
    
    display_progress();
}

Magic-1 Bootloader Technical Analysis - Part 49: Boot Memory Management

Memory Management Core Components

The memory management system handles dynamic memory allocation, memory mapping, and memory protection during the boot process.

Memory Manager Interface

#define PAGE_SIZE 2048
#define MAX_MEMORY_BLOCKS 256
#define MEMORY_ALIGNMENT 8

typedef struct memory_block {
    void* address;
    size_t size;
    bool free;
    struct memory_block* next;
} memory_block_t;

typedef struct {
    void* heap_start;
    void* heap_end;
    size_t total_size;
    size_t free_size;
    memory_block_t blocks[MAX_MEMORY_BLOCKS];
    uint16_t block_count;
} memory_manager_t;

Memory Manager Implementation

static memory_manager_t memory_ctx;

void init_memory_manager(void* start, size_t size) {
    memory_ctx.heap_start = (void*)((uintptr_t)(start + MEMORY_ALIGNMENT - 1) 
                                   & ~(MEMORY_ALIGNMENT - 1));
    memory_ctx.heap_end = (void*)((uintptr_t)start + size);
    memory_ctx.total_size = (uintptr_t)memory_ctx.heap_end - 
                           (uintptr_t)memory_ctx.heap_start;
    memory_ctx.free_size = memory_ctx.total_size;
    memory_ctx.block_count = 1;
    
    // Initialize first block as free
    memory_ctx.blocks[0].address = memory_ctx.heap_start;
    memory_ctx.blocks[0].size = memory_ctx.total_size;
    memory_ctx.blocks[0].free = true;
    memory_ctx.blocks[0].next = NULL;
}

void* boot_malloc(size_t size) {
    size_t aligned_size = (size + MEMORY_ALIGNMENT - 1) & ~(MEMORY_ALIGNMENT - 1);
    memory_block_t* block;
    
    for (uint16_t i = 0; i < memory_ctx.block_count; i++) {
        block = &memory_ctx.blocks[i];
        if (block->free && block->size >= aligned_size) {
            // Split block if possible
            if (block->size > aligned_size + sizeof(memory_block_t)) {
                memory_block_t* new_block = &memory_ctx.blocks[memory_ctx.block_count++];
                new_block->address = block->address + aligned_size;
                new_block->size = block->size - aligned_size;
                new_block->free = true;
                new_block->next = block->next;
                
                block->size = aligned_size;
                block->next = new_block;
            }
            
            block->free = false;
            memory_ctx.free_size -= block->size;
            return block->address;
        }
    }
    
    return NULL;
}

Magic-1 Bootloader Technical Analysis - Part 50: Boot Process Error Handling

Error Handler Core Components

The error handling system manages and responds to various error conditions during the boot process.

Error Handler Interface

#define MAX_ERROR_STACK 16
#define MAX_ERROR_MSG 128

typedef enum {
    ERR_NONE = 0,
    ERR_HARDWARE_INIT,
    ERR_MEMORY_INIT,
    ERR_DEVICE_INIT,
    ERR_CONFIG_LOAD,
    ERR_IMAGE_LOAD,
    ERR_CHECKSUM,
    ERR_TIMEOUT,
    ERR_FATAL
} error_code_t;

typedef struct {
    error_code_t code;
    char message[MAX_ERROR_MSG];
    uint32_t timestamp;
    const char* file;
    int line;
} error_info_t;

Error Handler Implementation

static struct {
    error_info_t error_stack[MAX_ERROR_STACK];
    uint8_t stack_ptr;
    bool panic_mode;
    void (*error_callback)(error_info_t*);
} error_ctx;

void handle_error(error_code_t code, const char* msg, const char* file, int line) {
    error_info_t* error;
    
    // Push error to stack
    if (error_ctx.stack_ptr < MAX_ERROR_STACK) {
        error = &error_ctx.error_stack[error_ctx.stack_ptr++];
        error->code = code;
        strncpy(error->message, msg, MAX_ERROR_MSG - 1);
        error->timestamp = get_system_time();
        error->file = file;
        error->line = line;
        
        // Call error callback if registered
        if (error_ctx.error_callback) {
            error_ctx.error_callback(error);
        }
        
        // Enter panic mode for fatal errors
        if (code == ERR_FATAL) {
            error_ctx.panic_mode = true;
            panic_handler();
        }
    }
}

void display_error_stack(void) {
    printf("\nError Stack Trace:\n");
    printf("=================\n");
    
    for (int i = error_ctx.stack_ptr - 1; i >= 0; i--) {
        error_info_t* error = &error_ctx.error_stack[i];
        printf("[%08x] %s:%d - %s\n",
               error->timestamp,
               error->file,
               error->line,
               error->message);
    }
}

Magic-1 Bootloader Technical Analysis - Part 51: Boot Device Discovery

Device Discovery System

The device discovery system automatically detects and initializes available boot devices during the boot process.

Device Discovery Interface

#define MAX_BOOT_DEVICES 8
#define MAX_DEVICE_NAME 32

typedef enum {
    DEV_TYPE_IDE,
    DEV_TYPE_FLASH,
    DEV_TYPE_MMC,
    DEV_TYPE_NET,
    DEV_TYPE_UNKNOWN
} device_type_t;

typedef struct {
    device_type_t type;
    uint16_t vendor_id;
    uint16_t device_id;
    char name[MAX_DEVICE_NAME];
    bool bootable;
    void* device_data;
} boot_device_t;

Device Discovery Manager

static struct {
    boot_device_t devices[MAX_BOOT_DEVICES];
    uint8_t device_count;
    bool discovery_complete;
} discovery_ctx;

int discover_boot_devices(void) {
    // Scan IDE/ATA devices
    scan_ide_devices();
    
    // Scan MMC/SD devices
    scan_mmc_devices();
    
    // Scan network interfaces
    scan_network_devices();
    
    discovery_ctx.discovery_complete = true;
    return discovery_ctx.device_count;
}

static void scan_ide_devices(void) {
    uint16_t base_ports[] = { 0x1F0, 0x170 };
    
    for (int i = 0; i < 2; i++) {
        uint16_t base = base_ports[i];
        uint8_t status = inb(base + 7);  // Read status register
        
        if (status != 0xFF) {  // Device present
            boot_device_t* dev = &discovery_ctx.devices[discovery_ctx.device_count++];
            dev->type = DEV_TYPE_IDE;
            dev->vendor_id = inw(base + 0);
            dev->device_id = inw(base + 2);
            snprintf(dev->name, MAX_DEVICE_NAME, "IDE%d", i);
            dev->bootable = check_bootable(dev);
        }
    }
}

Magic-1 Bootloader Technical Analysis - Part 52: Boot Process Reporting

Status Reporting System

The reporting system tracks and logs the boot process status, providing detailed information about each stage of system initialization.

Core Status Reporter Interface

#define MAX_STATUS_ENTRIES 64
#define MAX_STATUS_MSG 128
#define MAX_COMPONENT_NAME 32

typedef enum {
    STATUS_INFO,
    STATUS_WARNING,
    STATUS_ERROR,
    STATUS_DEBUG
} status_type_t;

typedef struct {
    uint32_t timestamp;
    status_type_t type;
    char component[MAX_COMPONENT_NAME];
    char message[MAX_STATUS_MSG];
    uint32_t sequence;
} status_entry_t;

Status Reporter Implementation

static struct {
    status_entry_t entries[MAX_STATUS_ENTRIES];
    uint32_t entry_count;
    uint32_t sequence_counter;
    bool console_output;
    bool file_output;
    char log_file[256];
} status_ctx;

void report_status(status_type_t type, const char* component, const char* format, ...) {
    status_entry_t* entry;
    va_list args;
    
    if (status_ctx.entry_count >= MAX_STATUS_ENTRIES) {
        // Rotate entries if buffer full
        memmove(&status_ctx.entries[0], 
                &status_ctx.entries[1], 
                sizeof(status_entry_t) * (MAX_STATUS_ENTRIES - 1));
        status_ctx.entry_count--;
    }
    
    entry = &status_ctx.entries[status_ctx.entry_count++];
    entry->timestamp = get_system_time();
    entry->type = type;
    entry->sequence = status_ctx.sequence_counter++;
    
    strncpy(entry->component, component, MAX_COMPONENT_NAME - 1);
    
    va_start(args, format);
    vsnprintf(entry->message, MAX_STATUS_MSG - 1, format, args);
    va_end(args);
    
    // Output to console if enabled
    if (status_ctx.console_output) {
        const char* type_str[] = {"INFO", "WARN", "ERROR", "DEBUG"};
        printf("[%08x][%s][%s] %s\n", 
               entry->timestamp,
               type_str[entry->type],
               entry->component,
               entry->message);
    }
}

Magic-1 Bootloader Technical Analysis - Part 53: Boot Process Statistics

The statistics system collects and analyzes performance metrics during the boot process.

Core Statistics Interface

#define MAX_STAT_COUNTERS 32
#define MAX_STAT_NAME 48

typedef enum {
    STAT_TYPE_COUNTER,
    STAT_TYPE_GAUGE,
    STAT_TYPE_TIMER
} stat_type_t;

typedef struct {
    char name[MAX_STAT_NAME];
    stat_type_t type;
    union {
        uint64_t counter;
        int64_t gauge;
        struct {
            uint32_t start;
            uint32_t total;
            uint32_t count;
        } timer;
    } value;
} boot_stat_t;

Statistics Manager Implementation

static struct {
    boot_stat_t stats[MAX_STAT_COUNTERS];
    uint16_t stat_count;
    uint32_t boot_start_time;
    bool collection_enabled;
} stats_ctx;

void init_boot_stats(void) {
    memset(&stats_ctx, 0, sizeof(stats_ctx));
    stats_ctx.boot_start_time = get_system_time();
    stats_ctx.collection_enabled = true;
    
    // Register core statistics
    register_counter("memory.allocations");
    register_counter("disk.reads");
    register_counter("disk.errors");
    register_gauge("memory.available");
    register_timer("boot.total_time");
}

void update_stat(const char* name, int64_t value) {
    boot_stat_t* stat = find_stat(name);
    if (stat && stats_ctx.collection_enabled) {
        switch (stat->type) {
            case STAT_TYPE_COUNTER:
                stat->value.counter += value;
                break;
            case STAT_TYPE_GAUGE:
                stat->value.gauge = value;
                break;
        }
    }
}

void start_timer(const char* name) {
    boot_stat_t* stat = find_stat(name);
    if (stat && stat->type == STAT_TYPE_TIMER) {
        stat->value.timer.start = get_system_time();
    }
}

void stop_timer(const char* name) {
    boot_stat_t* stat = find_stat(name);
    if (stat && stat->type == STAT_TYPE_TIMER) {
        uint32_t duration = get_system_time() - stat->value.timer.start;
        stat->value.timer.total += duration;
        stat->value.timer.count++;
    }
}

Magic-1 Bootloader Technical Analysis - Part 54: Boot Process Verification

The verification system ensures system integrity and validates critical boot components.

Core Verification Components

Verification Interface

#define MAX_VERIFY_CHECKS 32
#define HASH_LENGTH 32

typedef enum {
    VERIFY_MEMORY,
    VERIFY_DEVICE,
    VERIFY_IMAGE,
    VERIFY_CONFIG
} verify_type_t;

typedef struct {
    verify_type_t type;
    const char* component;
    uint8_t expected_hash[HASH_LENGTH];
    bool (*verify_func)(void* data);
    bool required;
} verify_check_t;

Verification Manager

static struct {
    verify_check_t checks[MAX_VERIFY_CHECKS];
    uint8_t check_count;
    uint32_t last_verify;
    bool verify_enabled;
} verify_ctx;

int register_verify_check(verify_check_t* check) {
    if (verify_ctx.check_count >= MAX_VERIFY_CHECKS) {
        return -1;
    }
    
    memcpy(&verify_ctx.checks[verify_ctx.check_count++], 
           check, sizeof(verify_check_t));
    return 0;
}

bool verify_boot_components(void) {
    bool success = true;
    
    for (int i = 0; i < verify_ctx.check_count; i++) {
        verify_check_t* check = &verify_ctx.checks[i];
        bool result = check->verify_func(NULL);
        
        if (!result && check->required) {
            log_error("Verification failed for %s", check->component);
            success = false;
        }
    }
    
    verify_ctx.last_verify = get_system_time();
    return success;
}

Magic-1 Bootloader Technical Analysis - Part 55: Boot Process Monitoring

The monitoring system provides real-time insight into the boot process, tracking key metrics and system health.

Monitoring Core Components

Monitor Interface

#define MAX_MONITORS 16
#define MAX_SAMPLES 128
#define MONITOR_INTERVAL_MS 100

typedef enum {
    MONITOR_CPU_USAGE,
    MONITOR_MEMORY_USAGE,
    MONITOR_DISK_IO,
    MONITOR_TEMPERATURE
} monitor_type_t;

struct monitor_sample {
    uint32_t timestamp;
    int64_t value;
};

struct monitor_config {
    monitor_type_t type;
    const char* name;
    uint32_t interval_ms;
    int64_t warning_threshold;
    int64_t critical_threshold;
    void (*callback)(int64_t value);
};

Monitor Implementation

static struct {
    struct monitor_config configs[MAX_MONITORS];
    struct monitor_sample samples[MAX_MONITORS][MAX_SAMPLES];
    uint8_t monitor_count;
    uint8_t sample_indices[MAX_MONITORS];
    bool monitoring_active;
} monitor_ctx;

void update_monitors(void) {
    uint32_t current_time = get_system_time();
    
    for (int i = 0; i < monitor_ctx.monitor_count; i++) {
        struct monitor_config* config = &monitor_ctx.configs[i];
        
        // Check if it's time to sample
        if ((current_time % config->interval_ms) == 0) {
            int64_t value = sample_monitor(config->type);
            uint8_t index = monitor_ctx.sample_indices[i];
            
            // Store sample
            monitor_ctx.samples[i][index].timestamp = current_time;
            monitor_ctx.samples[i][index].value = value;
            
            // Update index
            monitor_ctx.sample_indices[i] = (index + 1) % MAX_SAMPLES;
            
            // Check thresholds
            if (value >= config->critical_threshold) {
                log_critical("Monitor %s exceeded critical threshold: %lld",
                           config->name, value);
            } else if (value >= config->warning_threshold) {
                log_warning("Monitor %s exceeded warning threshold: %lld",
                           config->name, value);
            }
            
            // Execute callback if configured
            if (config->callback) {
                config->callback(value);
            }
        }
    }
}

Magic-1 Bootloader Technical Analysis - Part 56: Boot Configuration Validation

Configuration Validator Core

The configuration validation system ensures that boot parameters and settings are correct and consistent before the boot process begins.

Configuration Validation Interface

#define MAX_VALIDATORS 32
#define MAX_ERROR_MSG 128

typedef enum {
    VAL_TYPE_RANGE,
    VAL_TYPE_ENUM,
    VAL_TYPE_STRING,
    VAL_TYPE_DEPENDENCY
} validator_type_t;

typedef struct {
    const char* param_name;
    validator_type_t type;
    union {
        struct {
            int64_t min;
            int64_t max;
        } range;
        struct {
            const char** values;
            int count;
        } enum_values;
        struct {
            size_t min_len;
            size_t max_len;
            const char* pattern;
        } string;
        struct {
            const char* depends_on;
            const char* required_value;
        } dependency;
    };
    bool required;
    char error_msg[MAX_ERROR_MSG];
} config_validator_t;

Validator Implementation

static struct {
    config_validator_t validators[MAX_VALIDATORS];
    uint8_t validator_count;
    bool validation_enabled;
} validator_ctx;

int validate_config_param(const char* param_name, const char* value) {
    for (int i = 0; i < validator_ctx.validator_count; i++) {
        config_validator_t* val = &validator_ctx.validators[i];
        
        if (strcmp(val->param_name, param_name) == 0) {
            switch (val->type) {
                case VAL_TYPE_RANGE: {
                    int64_t num_val = strtoll(value, NULL, 0);
                    if (num_val < val->range.min || num_val > val->range.max) {
                        snprintf(val->error_msg, MAX_ERROR_MSG,
                                "Parameter %s value %ld outside range [%ld,%ld]",
                                param_name, num_val, 
                                val->range.min, val->range.max);
                        return -1;
                    }
                    break;
                }
                case VAL_TYPE_ENUM: {
                    bool found = false;
                    for (int j = 0; j < val->enum_values.count; j++) {
                        if (strcmp(value, val->enum_values.values[j]) == 0) {
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        snprintf(val->error_msg, MAX_ERROR_MSG,
                                "Invalid value for parameter %s", param_name);
                        return -1;
                    }
                    break;
                }
            }
            return 0;
        }
    }
    return -1;  // Validator not found
}

Magic-1 Bootloader Technical Analysis - Part 57: Boot Process Recovery

The recovery system provides mechanisms to handle boot failures and restore system functionality.

Core Recovery Components

Recovery Manager Interface

#define MAX_RECOVERY_ATTEMPTS 3
#define MAX_RECOVERY_POINTS 8

typedef enum {
    RECOVERY_NORMAL,
    RECOVERY_FALLBACK,
    RECOVERY_SAFE_MODE,
    RECOVERY_EMERGENCY
} recovery_mode_t;

typedef struct {
    uint32_t timestamp;
    recovery_mode_t mode;
    uint8_t boot_device;
    uint32_t config_version;
    char image_name[64];
} recovery_point_t;

Recovery Implementation

static struct {
    recovery_point_t points[MAX_RECOVERY_POINTS];
    uint8_t point_count;
    uint8_t attempt_count;
    recovery_mode_t current_mode;
    bool recovery_active;
} recovery_ctx;

int enter_recovery_mode(recovery_mode_t mode) {
    if (recovery_ctx.attempt_count >= MAX_RECOVERY_ATTEMPTS) {
        log_error("Maximum recovery attempts exceeded");
        return -1;
    }

    recovery_ctx.current_mode = mode;
    recovery_ctx.recovery_active = true;
    recovery_ctx.attempt_count++;

    // Create recovery point
    if (recovery_ctx.point_count < MAX_RECOVERY_POINTS) {
        recovery_point_t* point = &recovery_ctx.points[recovery_ctx.point_count++];
        point->timestamp = get_system_time();
        point->mode = mode;
        point->boot_device = get_current_boot_device();
        point->config_version = get_config_version();
        strncpy(point->image_name, get_boot_image_name(), 63);
    }

    // Apply recovery strategy
    switch (mode) {
        case RECOVERY_FALLBACK:
            return load_fallback_image();
            
        case RECOVERY_SAFE_MODE:
            return enter_safe_mode();
            
        case RECOVERY_EMERGENCY:
            return enter_emergency_shell();
            
        default:
            return -1;
    }
}

Magic-1 Bootloader Technical Analysis - Part 58: Boot Process Diagnostics

The diagnostics system provides tools for analyzing and troubleshooting boot-time issues.

Core Diagnostics Components

Diagnostics Interface

#define MAX_DIAG_TESTS 32
#define MAX_TEST_NAME 64
#define MAX_RESULT_MSG 128

typedef enum {
    DIAG_STATUS_PASS,
    DIAG_STATUS_FAIL,
    DIAG_STATUS_SKIP,
    DIAG_STATUS_ERROR
} diag_status_t;

typedef struct {
    char name[MAX_TEST_NAME];
    diag_status_t (*test_func)(void);
    bool enabled;
    uint32_t timeout_ms;
    char result[MAX_RESULT_MSG];
} diagnostic_test_t;

Diagnostics Manager Implementation

static struct {
    diagnostic_test_t tests[MAX_DIAG_TESTS];
    uint8_t test_count;
    bool diag_mode;
} diag_ctx;

void run_diagnostics(void) {
    printf("\nRunning Boot Diagnostics\n");
    printf("======================\n\n");

    uint32_t pass_count = 0;
    uint32_t fail_count = 0;

    for (int i = 0; i < diag_ctx.test_count; i++) {
        diagnostic_test_t* test = &diag_ctx.tests[i];
        
        if (!test->enabled) {
            continue;
        }

        printf("Running test: %s...", test->name);
        
        uint32_t start_time = get_system_time();
        diag_status_t status = test->test_func();
        uint32_t duration = get_system_time() - start_time;

        switch (status) {
            case DIAG_STATUS_PASS:
                printf("PASS (%dms)\n", duration);
                pass_count++;
                break;
                
            case DIAG_STATUS_FAIL:
                printf("FAIL (%dms)\n", duration);
                printf("  Error: %s\n", test->result);
                fail_count++;
                break;
                
            case DIAG_STATUS_SKIP:
                printf("SKIP\n");
                break;
                
            case DIAG_STATUS_ERROR:
                printf("ERROR (%dms)\n", duration);
                printf("  Error: %s\n", test->result);
                fail_count++;
                break;
        }
    }

    printf("\nDiagnostics Complete: %d passed, %d failed\n", 
           pass_count, fail_count);
}

Magic-1 Bootloader Technical Analysis - Part 59: Boot Process Optimization

The optimization system improves boot performance through caching, prefetching, and parallel initialization.

Core Optimization Components

Optimization Manager Interface

#define MAX_CACHE_ENTRIES 64
#define MAX_PREFETCH_QUEUE 32
#define CACHE_LINE_SIZE 256

typedef enum {
    OPT_LEVEL_NONE,
    OPT_LEVEL_BASIC,
    OPT_LEVEL_AGGRESSIVE,
    OPT_LEVEL_MAX
} opt_level_t;

struct cache_entry {
    uint32_t address;
    uint32_t size;
    uint32_t access_count;
    uint32_t last_access;
    uint8_t data[CACHE_LINE_SIZE];
};

Cache Implementation

static struct {
    struct cache_entry entries[MAX_CACHE_ENTRIES];
    uint16_t entry_count;
    uint32_t hits;
    uint32_t misses;
    bool enabled;
} cache_ctx;

void* optimized_read(uint32_t address, size_t size) {
    // Check cache first
    for (int i = 0; i < cache_ctx.entry_count; i++) {
        struct cache_entry* entry = &cache_ctx.entries[i];
        if (entry->address <= address && 
            address + size <= entry->address + entry->size) {
            cache_ctx.hits++;
            entry->access_count++;
            entry->last_access = get_system_time();
            return entry->data + (address - entry->address);
        }
    }

    // Cache miss - load from memory
    cache_ctx.misses++;
    if (cache_ctx.entry_count < MAX_CACHE_ENTRIES) {
        struct cache_entry* new_entry = &cache_ctx.entries[cache_ctx.entry_count++];
        new_entry->address = address & ~(CACHE_LINE_SIZE - 1);
        new_entry->size = CACHE_LINE_SIZE;
        new_entry->access_count = 1;
        new_entry->last_access = get_system_time();
        memcpy(new_entry->data, (void*)new_entry->address, CACHE_LINE_SIZE);
        return new_entry->data + (address - new_entry->address);
    }

    // Cache full - return direct memory access
    return (void*)address;
}

Magic-1 Bootloader Technical Analysis - Part 60: Boot Process Security

The security system implements core protection mechanisms to ensure secure boot operations and system integrity.

Security Manager Core Components

Security Definitions

#define HASH_LENGTH 32
#define KEY_LENGTH 64
#define MAX_SIGNATURES 4

typedef enum {
    SEC_LEVEL_DISABLED,
    SEC_LEVEL_BASIC,
    SEC_LEVEL_STRICT,
    SEC_LEVEL_MAX
} security_level_t;

typedef struct {
    uint8_t hash[HASH_LENGTH];
    uint8_t signature[KEY_LENGTH];
    uint32_t timestamp;
    uint32_t flags;
} security_header_t;

Security Implementation

static struct {
    security_level_t current_level;
    uint8_t public_key[KEY_LENGTH];
    bool secure_boot;
    uint32_t boot_count;
    security_header_t last_boot;
} security_ctx;

int verify_boot_image(const uint8_t* image, size_t size) {
    security_header_t* header = (security_header_t*)image;
    uint8_t computed_hash[HASH_LENGTH];
    
    // Verify image size
    if (size < sizeof(security_header_t)) {
        return -1;
    }
    
    // Calculate image hash
    sha256_calculate(image + sizeof(security_header_t),
                    size - sizeof(security_header_t),
                    computed_hash);
                    
    // Compare hashes
    if (memcmp(computed_hash, header->hash, HASH_LENGTH) != 0) {
        log_error("Image hash verification failed");
        return -2;
    }
    
    // Verify signature if secure boot enabled
    if (security_ctx.secure_boot) {
        if (!verify_signature(computed_hash,
                            header->signature,
                            security_ctx.public_key)) {
            log_error("Image signature verification failed");
            return -3;
        }
    }
    
    // Store last successful boot info
    memcpy(&security_ctx.last_boot, header, sizeof(security_header_t));
    security_ctx.boot_count++;
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 61: Boot Process Logging

Logging System Architecture

The logging system provides structured logging capabilities for tracking boot-time events and diagnostics.

Core Logging Interface

#define LOG_BUFFER_SIZE 4096
#define MAX_LOG_ENTRY_SIZE 256
#define MAX_LOG_HANDLERS 8

typedef enum {
    LOG_LEVEL_DEBUG,
    LOG_LEVEL_INFO, 
    LOG_LEVEL_WARN,
    LOG_LEVEL_ERROR,
    LOG_LEVEL_FATAL
} log_level_t;

typedef struct {
    uint32_t timestamp;
    log_level_t level;
    uint32_t sequence;
    const char* source;
    char message[MAX_LOG_ENTRY_SIZE];
} log_entry_t;

Logging Manager Implementation

static struct {
    uint8_t buffer[LOG_BUFFER_SIZE];
    uint32_t write_pos;
    uint32_t sequence;
    log_level_t min_level;
    void (*handlers[MAX_LOG_HANDLERS])(const log_entry_t*);
    uint8_t handler_count;
} log_ctx;

void log_message(log_level_t level, const char* source, const char* fmt, ...) {
    if (level < log_ctx.min_level) {
        return;
    }

    va_list args;
    log_entry_t entry;
    
    // Initialize entry
    entry.timestamp = get_system_time();
    entry.level = level;
    entry.sequence = log_ctx.sequence++;
    entry.source = source;
    
    // Format message
    va_start(args, fmt);
    vsnprintf(entry.message, MAX_LOG_ENTRY_SIZE - 1, fmt, args);
    va_end(args);

    // Write to circular buffer
    size_t entry_size = sizeof(log_entry_t);
    if (log_ctx.write_pos + entry_size > LOG_BUFFER_SIZE) {
        log_ctx.write_pos = 0;
    }
    
    memcpy(&log_ctx.buffer[log_ctx.write_pos], &entry, entry_size);
    log_ctx.write_pos += entry_size;

    // Call registered handlers
    for (int i = 0; i < log_ctx.handler_count; i++) {
        if (log_ctx.handlers[i]) {
            log_ctx.handlers[i](&entry);
        }
    }
}

Magic-1 Bootloader Technical Analysis - Part 62: Boot Process Timing Analysis

The timing analysis system measures and profiles various aspects of the boot sequence for optimization purposes.

Core Timing Components

Timing Analyzer Interface

#define MAX_TIME_POINTS 64
#define MAX_TIMING_NAME 32

typedef struct {
    char name[MAX_TIMING_NAME];
    uint32_t start_time;
    uint32_t duration;
    uint32_t min_time;
    uint32_t max_time;
    uint32_t count;
    bool active;
} timing_point_t;

Timing Manager Implementation

struct timing_context {
    timing_point_t points[MAX_TIME_POINTS];
    uint16_t point_count;
    uint32_t boot_start;
    bool timing_enabled;
};

static struct timing_context timing_ctx;

void start_timing(const char* name) {
    for (int i = 0; i < timing_ctx.point_count; i++) {
        timing_point_t* point = &timing_ctx.points[i];
        if (strcmp(point->name, name) == 0) {
            point->start_time = get_system_time();
            point->active = true;
            return;
        }
    }
    
    // New timing point
    if (timing_ctx.point_count < MAX_TIME_POINTS) {
        timing_point_t* new_point = &timing_ctx.points[timing_ctx.point_count++];
        strncpy(new_point->name, name, MAX_TIMING_NAME - 1);
        new_point->start_time = get_system_time();
        new_point->min_time = UINT32_MAX;
        new_point->active = true;
    }
}

void stop_timing(const char* name) {
    uint32_t end_time = get_system_time();
    
    for (int i = 0; i < timing_ctx.point_count; i++) {
        timing_point_t* point = &timing_ctx.points[i];
        if (strcmp(point->name, name) == 0 && point->active) {
            uint32_t duration = end_time - point->start_time;
            point->duration += duration;
            point->count++;
            point->active = false;
            
            if (duration < point->min_time) {
                point->min_time = duration;
            }
            if (duration > point->max_time) {
                point->max_time = duration;
            }
            break;
        }
    }
}

Magic-1 Bootloader Technical Analysis - Part 63: Boot Process Resource Management

The resource management system tracks and controls system resources during the boot process to ensure efficient allocation and prevent conflicts.

Resource Manager Core Components

Resource Management Interface

#define MAX_RESOURCES 32
#define MAX_RESOURCE_NAME 48

typedef enum {
    RESOURCE_MEMORY,
    RESOURCE_IO_PORT,
    RESOURCE_IRQ,
    RESOURCE_DMA
} resource_type_t;

typedef struct {
    char name[MAX_RESOURCE_NAME];
    resource_type_t type;
    uint32_t start;
    uint32_t size;
    bool allocated;
    const char* owner;
} resource_t;

Resource Manager Implementation

static struct {
    resource_t resources[MAX_RESOURCES];
    uint16_t resource_count;
    bool tracking_enabled;
    uint32_t allocation_count;
} resource_ctx;

void* allocate_resource(resource_type_t type, uint32_t size, const char* owner) {
    if (!resource_ctx.tracking_enabled) {
        return NULL;
    }

    // Find available resource
    for (int i = 0; i < resource_ctx.resource_count; i++) {
        resource_t* res = &resource_ctx.resources[i];
        if (!res->allocated && res->type == type && res->size >= size) {
            res->allocated = true;
            res->owner = owner;
            resource_ctx.allocation_count++;
            
            log_info("Resource allocated: %s by %s", res->name, owner);
            return (void*)res->start;
        }
    }

    log_error("Failed to allocate resource type %d size %d for %s", 
              type, size, owner);
    return NULL;
}

Magic-1 Bootloader Technical Analysis - Part 64: Boot Process Power Management

The power management system controls system power states and transitions during the boot process.

Power Management Interface

#define MAX_POWER_STATES 8
#define MAX_STATE_NAME 32

typedef enum {
    POWER_STATE_FULL,    // Full power, all systems running
    POWER_STATE_NORMAL,  // Normal operation
    POWER_STATE_SAVE,    // Power saving mode
    POWER_STATE_STANDBY, // Standby mode
    POWER_STATE_OFF      // Power off
} power_state_t;

struct power_transition {
    power_state_t from_state;
    power_state_t to_state;
    uint32_t transition_time_ms;
    void (*pre_transition)(void);
    void (*post_transition)(void);
};

Power Manager Implementation

static struct {
    power_state_t current_state;
    power_state_t target_state;
    struct power_transition transitions[MAX_POWER_STATES];
    uint8_t transition_count;
    uint32_t last_transition;
    bool power_mgmt_enabled;
} power_ctx;

int set_power_state(power_state_t new_state) {
    if (!power_ctx.power_mgmt_enabled) {
        return -1;
    }

    // Find valid transition
    for (int i = 0; i < power_ctx.transition_count; i++) {
        struct power_transition* trans = &power_ctx.transitions[i];
        if (trans->from_state == power_ctx.current_state && 
            trans->to_state == new_state) {
            
            // Execute pre-transition handler
            if (trans->pre_transition) {
                trans->pre_transition();
            }
            
            // Update hardware power state
            uint16_t power_ctrl = read_power_control();
            power_ctrl &= ~POWER_STATE_MASK;
            power_ctrl |= (new_state << POWER_STATE_SHIFT);
            write_power_control(power_ctrl);
            
            // Wait for transition
            delay_ms(trans->transition_time_ms);
            
            // Execute post-transition handler
            if (trans->post_transition) {
                trans->post_transition();
            }
            
            power_ctx.current_state = new_state;
            power_ctx.last_transition = get_system_time();
            
            return 0;
        }
    }
    
    return -1;  // Invalid transition
}

Magic-1 Bootloader Technical Analysis - Part 65: Boot Process Hardware Detection

The hardware detection system identifies and configures system components during early boot.

Hardware Detection Manager

Core Detection Interface

#define MAX_DEVICES 32
#define MAX_DEVICE_NAME 48
#define VENDOR_ID_MAGIC1 0x4D31

typedef enum {
    DEV_CLASS_CPU,
    DEV_CLASS_MEMORY,
    DEV_CLASS_STORAGE,
    DEV_CLASS_NETWORK,
    DEV_CLASS_DISPLAY,
    DEV_CLASS_INPUT
} device_class_t;

struct device_info {
    char name[MAX_DEVICE_NAME];
    device_class_t class;
    uint16_t vendor_id;
    uint16_t device_id;
    uint16_t subsystem_id;
    uint8_t revision;
    bool enabled;
    void* driver_data;
};

Hardware Detection Implementation

static struct {
    struct device_info devices[MAX_DEVICES];
    uint16_t device_count;
    bool detection_complete;
} hw_ctx;

int detect_hardware(void) {
    log_info("Starting hardware detection...");
    
    // Detect CPU and core system components
    detect_cpu_info();
    
    // Scan system bus for devices
    scan_system_bus();
    
    // Detect memory configuration
    detect_memory_config();
    
    // Detect storage devices
    detect_storage_devices();
    
    hw_ctx.detection_complete = true;
    
    log_info("Hardware detection complete. Found %d devices", 
             hw_ctx.device_count);
             
    return hw_ctx.device_count;
}

static void scan_system_bus(void) {
    // Scan IO space for Magic-1 devices
    for (uint16_t addr = 0x100; addr < 0x1000; addr += 2) {
        uint16_t vendor = read_io16(addr);
        if (vendor == VENDOR_ID_MAGIC1) {
            uint16_t device = read_io16(addr + 2);
            register_device(addr, vendor, device);
        }
    }
}

Magic-1 Bootloader Technical Analysis - Part 66: Boot Process Device Initialization

The device initialization system manages the ordered startup sequence of detected hardware components.

Device Initialization Manager

Core Initialization Interface

#define MAX_INIT_HANDLERS 32
#define MAX_DEPENDENCIES 8

typedef enum {
    INIT_PHASE_EARLY,    // Basic hardware setup
    INIT_PHASE_CORE,     // Core system devices
    INIT_PHASE_STORAGE,  // Storage devices
    INIT_PHASE_NET,      // Network interfaces
    INIT_PHASE_LATE      // Optional devices
} init_phase_t;

struct init_handler {
    const char* device_name;
    init_phase_t phase;
    int (*init_func)(void);
    const char* dependencies[MAX_DEPENDENCIES];
    bool initialized;
    uint32_t init_time;
};

Device Initializer Implementation

static struct {
    struct init_handler handlers[MAX_INIT_HANDLERS];
    uint16_t handler_count;
    init_phase_t current_phase;
    bool init_complete;
} init_ctx;

int initialize_devices(void) {
    int result = 0;
    
    for (init_phase_t phase = INIT_PHASE_EARLY; phase <= INIT_PHASE_LATE; phase++) {
        init_ctx.current_phase = phase;
        log_info("Starting device initialization phase %d", phase);
        
        // Initialize all devices in current phase
        for (int i = 0; i < init_ctx.handler_count; i++) {
            struct init_handler* handler = &init_ctx.handlers[i];
            
            if (handler->phase == phase && !handler->initialized) {
                // Check dependencies
                bool deps_met = true;
                for (int d = 0; d < MAX_DEPENDENCIES && handler->dependencies[d]; d++) {
                    if (!is_device_initialized(handler->dependencies[d])) {
                        deps_met = false;
                        break;
                    }
                }
                
                if (deps_met) {
                    uint32_t start_time = get_system_time();
                    result = handler->init_func();
                    handler->init_time = get_system_time() - start_time;
                    
                    if (result == 0) {
                        handler->initialized = true;
                        log_info("Initialized %s in %dms", 
                                handler->device_name, handler->init_time);
                    } else {
                        log_error("Failed to initialize %s: error %d",
                                 handler->device_name, result);
                        return result;
                    }
                }
            }
        }
    }
    
    init_ctx.init_complete = true;
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 67: Boot Process Configuration Management

The configuration management system handles dynamic configuration settings and their persistence during the boot process.

Configuration Manager Interface

#define MAX_CONFIG_ENTRIES 128
#define MAX_KEY_LENGTH 64
#define MAX_VALUE_LENGTH 256
#define CONFIG_MAGIC 0x4D314346  // "M1CF"

typedef enum {
    CONFIG_TYPE_STRING,
    CONFIG_TYPE_INTEGER,
    CONFIG_TYPE_BOOLEAN,
    CONFIG_TYPE_ARRAY
} config_type_t;

struct config_entry {
    char key[MAX_KEY_LENGTH];
    config_type_t type;
    union {
        char string_value[MAX_VALUE_LENGTH];
        int64_t int_value;
        bool bool_value;
        struct {
            uint8_t* data;
            size_t length;
        } array_value;
    };
};

Configuration Manager Implementation

static struct {
    struct config_entry entries[MAX_CONFIG_ENTRIES];
    uint16_t entry_count;
    bool modified;
    uint32_t last_save;
} config_ctx;

int set_config_value(const char* key, const void* value, config_type_t type) {
    struct config_entry* entry = NULL;
    
    // Look for existing entry
    for (int i = 0; i < config_ctx.entry_count; i++) {
        if (strcmp(config_ctx.entries[i].key, key) == 0) {
            entry = &config_ctx.entries[i];
            break;
        }
    }
    
    // Create new entry if not found
    if (!entry && config_ctx.entry_count < MAX_CONFIG_ENTRIES) {
        entry = &config_ctx.entries[config_ctx.entry_count++];
        strncpy(entry->key, key, MAX_KEY_LENGTH - 1);
    }
    
    if (!entry) {
        return -1;  // No space for new entry
    }
    
    // Update value based on type
    entry->type = type;
    switch (type) {
        case CONFIG_TYPE_STRING:
            strncpy(entry->string_value, (const char*)value, MAX_VALUE_LENGTH - 1);
            break;
        case CONFIG_TYPE_INTEGER:
            entry->int_value = *(const int64_t*)value;
            break;
        case CONFIG_TYPE_BOOLEAN:
            entry->bool_value = *(const bool*)value;
            break;
        case CONFIG_TYPE_ARRAY:
            // Handle array values
            break;
    }
    
    config_ctx.modified = true;
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 68: Boot Process Device Tree Management

Device Tree Management System

The device tree system provides a structured representation of hardware devices and their relationships during boot.

Core Device Tree Interface

#define MAX_DT_NODES 64
#define MAX_DT_PROPS 16
#define MAX_NODE_NAME 48

typedef enum {
    DT_PROP_STRING,
    DT_PROP_INTEGER,
    DT_PROP_ARRAY,
    DT_PROP_REFERENCE
} dt_prop_type_t;

struct dt_property {
    char name[MAX_NODE_NAME];
    dt_prop_type_t type;
    union {
        char* string_value;
        uint64_t int_value;
        struct {
            void* data;
            size_t length;
        } array;
        struct dt_node* ref;
    };
};

struct dt_node {
    char name[MAX_NODE_NAME];
    struct dt_property properties[MAX_DT_PROPS];
    uint8_t prop_count;
    struct dt_node* parent;
    struct dt_node* children[MAX_DT_NODES];
    uint8_t child_count;
};

Device Tree Manager Implementation

static struct {
    struct dt_node root_node;
    struct dt_node nodes[MAX_DT_NODES];
    uint16_t node_count;
    bool initialized;
} dt_ctx;

struct dt_node* create_dt_node(const char* name, struct dt_node* parent) {
    if (dt_ctx.node_count >= MAX_DT_NODES) {
        return NULL;
    }

    struct dt_node* node = &dt_ctx.nodes[dt_ctx.node_count++];
    strncpy(node->name, name, MAX_NODE_NAME - 1);
    node->parent = parent;
    
    if (parent) {
        if (parent->child_count < MAX_DT_NODES) {
            parent->children[parent->child_count++] = node;
        }
    }
    
    return node;
}

int add_dt_property(struct dt_node* node, const char* name, 
                   dt_prop_type_t type, const void* value) {
    if (node->prop_count >= MAX_DT_PROPS) {
        return -1;
    }

    struct dt_property* prop = &node->properties[node->prop_count++];
    strncpy(prop->name, name, MAX_NODE_NAME - 1);
    prop->type = type;

    switch (type) {
        case DT_PROP_STRING:
            prop->string_value = strdup((const char*)value);
            break;
        case DT_PROP_INTEGER:
            prop->int_value = *(const uint64_t*)value;
            break;
        case DT_PROP_REFERENCE:
            prop->ref = (struct dt_node*)value;
            break;
        case DT_PROP_ARRAY:
            // Handle array properties
            break;
    }
    
    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 69: Boot Process Firmware Interface

The firmware interface provides a standardized way to interact with platform firmware services during boot.

Core Firmware Interface

#define FW_MAX_SERVICES 16
#define FW_SERVICE_NAME_MAX 32

typedef enum {
    FW_STATUS_SUCCESS = 0,
    FW_STATUS_INVALID_PARAMETER = 1,
    FW_STATUS_UNSUPPORTED = 2,
    FW_STATUS_NOT_READY = 3,
    FW_STATUS_DEVICE_ERROR = 4,
    FW_STATUS_BUFFER_TOO_SMALL = 5
} fw_status_t;

struct fw_service {
    char name[FW_SERVICE_NAME_MAX];
    uint32_t version;
    fw_status_t (*init)(void);
    fw_status_t (*get_info)(void* buffer, size_t* size);
    fw_status_t (*call)(uint32_t function, void* params);
};

Firmware Service Manager Implementation

static struct {
    struct fw_service services[FW_MAX_SERVICES];
    uint8_t service_count;
    bool initialized;
} fw_ctx;

fw_status_t fw_register_service(const struct fw_service* service) {
    if (fw_ctx.service_count >= FW_MAX_SERVICES) {
        return FW_STATUS_BUFFER_TOO_SMALL;
    }

    struct fw_service* new_service = &fw_ctx.services[fw_ctx.service_count++];
    memcpy(new_service, service, sizeof(struct fw_service));

    if (new_service->init) {
        return new_service->init();
    }

    return FW_STATUS_SUCCESS;
}

fw_status_t fw_call_service(const char* name, uint32_t function, void* params) {
    for (int i = 0; i < fw_ctx.service_count; i++) {
        if (strcmp(fw_ctx.services[i].name, name) == 0) {
            return fw_ctx.services[i].call(function, params);
        }
    }
    return FW_STATUS_UNSUPPORTED;
}

Magic-1 Bootloader Technical Analysis - Part 70: Boot Process Memory Protection

The memory protection system ensures secure memory access and isolation during the boot process.

Memory Protection Interface

#define MAX_PROTECTED_REGIONS 16
#define PAGE_SIZE 4096

typedef enum {
    PROT_NONE  = 0x0,
    PROT_READ  = 0x1,
    PROT_WRITE = 0x2,
    PROT_EXEC  = 0x4
} mem_prot_flags_t;

struct protected_region {
    void* start_addr;
    size_t size;
    mem_prot_flags_t flags;
    const char* owner;
    bool locked;
};

struct mpu_context {
    struct protected_region regions[MAX_PROTECTED_REGIONS];
    uint8_t region_count;
    bool mpu_enabled;
};

Memory Protection Implementation

static struct mpu_context mpu_ctx;

int protect_memory_region(void* addr, size_t size, mem_prot_flags_t flags, const char* owner) {
    if (mpu_ctx.region_count >= MAX_PROTECTED_REGIONS) {
        return -1;
    }

    // Align address and size to page boundaries
    void* aligned_addr = (void*)((uintptr_t)addr & ~(PAGE_SIZE - 1));
    size_t aligned_size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);

    struct protected_region* region = &mpu_ctx.regions[mpu_ctx.region_count++];
    region->start_addr = aligned_addr;
    region->size = aligned_size;
    region->flags = flags;
    region->owner = owner;
    region->locked = false;

    // Configure MPU hardware
    uint32_t mpu_base = (uint32_t)aligned_addr;
    uint32_t mpu_attr = flags | MPU_REGION_ENABLE;
    
    write_mpu_region(mpu_ctx.region_count - 1, mpu_base, mpu_attr);

    return 0;
}

Magic-1 Bootloader Technical Analysis - Part 71: Boot Process Exception Handling

The exception handling system manages hardware and software exceptions during the boot process, providing graceful error recovery and debugging information.

Exception Handler Interface

#define MAX_EXCEPTION_HANDLERS 16
#define MAX_EXCEPTION_NAME 32
#define EXCEPTION_STACK_SIZE 2048

typedef enum {
    EXC_RESET = 0,
    EXC_UNDEFINED_INSTRUCTION = 1,
    EXC_MEMORY_FAULT = 2,
    EXC_BUS_ERROR = 3,
    EXC_ILLEGAL_ACCESS = 4,
    EXC_DIVIDE_BY_ZERO = 5,
    EXC_PRIVILEGED = 6
} exception_type_t;

struct exception_frame {
    uint32_t r0;
    uint32_t r1;
    uint32_t r2;
    uint32_t r3;
    uint32_t r12;
    uint32_t lr;
    uint32_t pc;
    uint32_t psr;
};

typedef void (*exception_handler_t)(exception_type_t type, 
                                  struct exception_frame* frame);

Exception Manager Implementation

static struct {
    exception_handler_t handlers[MAX_EXCEPTION_HANDLERS];
    uint8_t handler_count;
    uint32_t exception_stack[EXCEPTION_STACK_SIZE];
    uint32_t exception_count;
    bool handling_exception;
} exc_ctx;

void register_exception_handler(exception_handler_t handler) {
    if (exc_ctx.handler_count < MAX_EXCEPTION_HANDLERS) {
        exc_ctx.handlers[exc_ctx.handler_count++] = handler;
    }
}

void __attribute__((interrupt)) handle_exception(void) {
    struct exception_frame* frame;
    exception_type_t type;

    // Get exception information
    type = get_exception_type();
    frame = get_exception_frame();

    // Prevent recursive exceptions
    if (exc_ctx.handling_exception) {
        panic_handler();
        return;
    }

    exc_ctx.handling_exception = true;
    exc_ctx.exception_count++;

    // Call registered handlers
    for (int i = 0; i < exc_ctx.handler_count; i++) {
        if (exc_ctx.handlers[i]) {
            exc_ctx.handlers[i](type, frame);
        }
    }

    exc_ctx.handling_exception = false;
}

Magic-1 Bootloader Technical Analysis - Part 72: Boot Process Cache Management

The cache management system optimizes memory access patterns during boot by managing instruction and data caches.

Cache Controller Interface

#define CACHE_LINE_SIZE 32
#define CACHE_WAYS 4
#define CACHE_SETS 256

typedef enum {
    CACHE_TYPE_INSTRUCTION,
    CACHE_TYPE_DATA,
    CACHE_TYPE_UNIFIED
} cache_type_t;

struct cache_info {
    cache_type_t type;
    uint32_t line_size;
    uint32_t ways;
    uint32_t sets;
    uint32_t total_size;
    bool enabled;
};

struct cache_stats {
    uint32_t hits;
    uint32_t misses;
    uint32_t evictions;
    uint32_t writebacks;
};

Cache Manager Implementation

static struct {
    struct cache_info i_cache;
    struct cache_info d_cache;
    struct cache_stats i_stats;
    struct cache_stats d_stats;
    bool cache_enabled;
} cache_ctx;

void init_cache_controller(void) {
    // Initialize instruction cache
    cache_ctx.i_cache.type = CACHE_TYPE_INSTRUCTION;
    cache_ctx.i_cache.line_size = CACHE_LINE_SIZE;
    cache_ctx.i_cache.ways = CACHE_WAYS;
    cache_ctx.i_cache.sets = CACHE_SETS;
    cache_ctx.i_cache.total_size = CACHE_LINE_SIZE * CACHE_WAYS * CACHE_SETS;
    
    // Initialize data cache
    cache_ctx.d_cache.type = CACHE_TYPE_DATA;
    cache_ctx.d_cache.line_size = CACHE_LINE_SIZE;
    cache_ctx.d_cache.ways = CACHE_WAYS;
    cache_ctx.d_cache.sets = CACHE_SETS;
    cache_ctx.d_cache.total_size = CACHE_LINE_SIZE * CACHE_WAYS * CACHE_SETS;
    
    // Clear statistics
    memset(&cache_ctx.i_stats, 0, sizeof(struct cache_stats));
    memset(&cache_ctx.d_stats, 0, sizeof(struct cache_stats));
    
    // Enable caches
    enable_caches();
    cache_ctx.cache_enabled = true;
}

Magic-1 Bootloader Technical Analysis - Part 73: Boot Process Interrupt Management

The interrupt management system handles hardware and software interrupts during the boot process, providing prioritized interrupt handling and routing.

Interrupt Controller Interface

#define MAX_IRQ_HANDLERS 32
#define MAX_IRQ_PRIORITY 16

typedef enum {
    IRQ_TIMER = 0,
    IRQ_UART = 1,
    IRQ_DMA = 2,
    IRQ_DISK = 3,
    IRQ_NET = 4,
    IRQ_GPIO = 5
} irq_number_t;

struct irq_handler {
    void (*handler)(void* context);
    void* context;
    uint8_t priority;
    bool enabled;
};

Interrupt Manager Implementation

static struct {
    struct irq_handler handlers[MAX_IRQ_HANDLERS];
    uint32_t pending_irqs;
    uint8_t current_priority;
    bool interrupts_enabled;
} irq_ctx;

void register_irq_handler(irq_number_t irq, void (*handler)(void*), 
                         void* context, uint8_t priority) {
    if (irq < MAX_IRQ_HANDLERS) {
        irq_ctx.handlers[irq].handler = handler;
        irq_ctx.handlers[irq].context = context;
        irq_ctx.handlers[irq].priority = priority;
        irq_ctx.handlers[irq].enabled = true;
        
        // Configure hardware interrupt controller
        write_irq_priority(irq, priority);
        enable_irq(irq);
    }
}

void __attribute__((interrupt)) irq_dispatcher(void) {
    uint32_t active_irqs = read_pending_irqs();
    
    // Process IRQs in priority order
    for (int i = 0; i < MAX_IRQ_HANDLERS; i++) {
        if ((active_irqs & (1 << i)) && irq_ctx.handlers[i].enabled) {
            if (irq_ctx.handlers[i].priority > irq_ctx.current_priority) {
                irq_ctx.current_priority = irq_ctx.handlers[i].priority;
                irq_ctx.handlers[i].handler(irq_ctx.handlers[i].context);
                irq_ctx.current_priority = 0;
            }
        }
    }
}

Magic-1 Bootloader Technical Analysis - Part 74: Boot Process Timer Management

Timer Management System

The timer management system provides precise timing services and delays during the boot process.

Timer Controller Interface

#define MAX_TIMERS 16
#define TIMER_BASE_FREQ 1000000  // 1MHz base frequency

typedef enum {
    TIMER_MODE_ONESHOT,
    TIMER_MODE_PERIODIC,
    TIMER_MODE_PWM
} timer_mode_t;

struct timer_config {
    uint32_t period_us;     // Period in microseconds
    timer_mode_t mode;
    void (*callback)(void* context);
    void* context;
    bool enabled;
};

Timer Manager Implementation

static struct {
    struct timer_config timers[MAX_TIMERS];
    uint8_t timer_count;
    uint64_t system_ticks;
    bool initialized;
} timer_ctx;

int init_timer_system(void) {
    // Configure hardware timer base
    write_timer_ctrl(TIMER_ENABLE | TIMER_INTERRUPT);
    write_timer_prescale(TIMER_BASE_FREQ / 1000);  // 1ms tick
    write_timer_period(1000);  // 1ms period
    
    timer_ctx.initialized = true;
    return 0;
}

int create_timer(const struct timer_config* config) {
    if (timer_ctx.timer_count >= MAX_TIMERS) {
        return -1;
    }

    struct timer_config* timer = &timer_ctx.timers[timer_ctx.timer_count++];
    memcpy(timer, config, sizeof(struct timer_config));

    // Configure hardware timer channel if available
    if (timer->mode == TIMER_MODE_PERIODIC) {
        configure_hw_timer(timer_ctx.timer_count - 1, timer->period_us);
    }

    return timer_ctx.timer_count - 1;
}

void __attribute__((interrupt)) timer_isr(void) {
    timer_ctx.system_ticks++;
    
    for (int i = 0; i < timer_ctx.timer_count; i++) {
        struct timer_config* timer = &timer_ctx.timers[i];
        if (timer->enabled && timer->callback) {
            timer->callback(timer->context);
        }
    }
}

Magic-1 Bootloader Technical Analysis - Part 75: Boot Process Power State Management

The power state management system handles system power transitions and power saving modes during boot.

Core Power Management Interface

#define MAX_POWER_STATES 8
#define MAX_POWER_HANDLERS 16

typedef enum {
    POWER_STATE_FULL,     // Full power mode
    POWER_STATE_LOW,      // Low power mode
    POWER_STATE_STANDBY,  // Standby mode
    POWER_STATE_SLEEP     // Deep sleep mode
} power_state_t;

struct power_transition {
    power_state_t from_state;
    power_state_t to_state;
    uint32_t transition_time_ms;
    int (*pre_transition)(void);
    int (*post_transition)(void);
};

Power State Manager Implementation

static struct {
    power_state_t current_state;
    struct power_transition transitions[MAX_POWER_STATES];
    uint8_t transition_count;
    void (*state_handlers[MAX_POWER_HANDLERS])(power_state_t);
    uint8_t handler_count;
    bool power_mgmt_enabled;
} power_ctx;

int transition_power_state(power_state_t target_state) {
    // Find valid transition
    for (int i = 0; i < power_ctx.transition_count; i++) {
        struct power_transition* trans = &power_ctx.transitions[i];
        if (trans->from_state == power_ctx.current_state &&
            trans->to_state == target_state) {
            
            // Execute pre-transition handler
            if (trans->pre_transition && trans->pre_transition() != 0) {
                return -1;
            }

            // Configure hardware power state
            set_hw_power_state(target_state);
            
            // Wait for transition
            delay_ms(trans->transition_time_ms);
            
            // Execute post-transition handler
            if (trans->post_transition && trans->post_transition() != 0) {
                return -2;
            }
            
            // Update state and notify handlers
            power_ctx.current_state = target_state;
            notify_power_handlers(target_state);
            
            return 0;
        }
    }
    
    return -3;  // No valid transition found
}

Magic-1 Bootloader Technical Analysis - Part 76: Boot Process Device Enumeration

The device enumeration system discovers and catalogs hardware devices present in the system during boot.

Core Device Enumerator

#define MAX_DEVICES 32
#define MAX_DEVICE_NAME 48
#define VENDOR_ID_MAGIC1 0x4D31

typedef enum {
    BUS_TYPE_NONE,
    BUS_TYPE_ISA,
    BUS_TYPE_PCI,
    BUS_TYPE_USB
} bus_type_t;

struct device_descriptor {
    char name[MAX_DEVICE_NAME];
    bus_type_t bus_type;
    uint16_t vendor_id;
    uint16_t device_id;
    uint16_t class_code;
    uint8_t revision;
    void* driver;
    bool active;
};

Device Enumerator Implementation

static struct {
    struct device_descriptor devices[MAX_DEVICES];
    uint16_t device_count;
    bool enumeration_complete;
} enum_ctx;

int enumerate_devices(void) {
    // Scan ISA bus
    scan_isa_bus();
    
    // Scan PCI bus if present
    if (is_pci_present()) {
        scan_pci_bus();
    }
    
    // Scan USB controllers if present
    scan_usb_controllers();
    
    enum_ctx.enumeration_complete = true;
    return enum_ctx.device_count;
}

static void scan_isa_bus(void) {
    // Scan known ISA ports for Magic-1 devices
    for (uint16_t port = 0x100; port < 0x3FF; port += 2) {
        uint16_t vendor = inw(port);
        if (vendor == VENDOR_ID_MAGIC1) {
            struct device_descriptor* dev = 
                &enum_ctx.devices[enum_ctx.device_count++];
            dev->bus_type = BUS_TYPE_ISA;
            dev->vendor_id = vendor;
            dev->device_id = inw(port + 2);
            identify_device(dev);
        }
    }
}
⚠️ **GitHub.com Fallback** ⚠️