title: [Writing an OS Kernel from Scratch] 335 – ARM Architecture Boot: From Power-On to Kernel
category: os
tag: [arm, boot, embedded, u-boot]
source: https://github.com/golang12306/os-kernel-from-scratch
[Writing an OS Kernel from Scratch] 335 – ARM Architecture Boot: From Power-On to Kernel
1. ARM Boot Sequence Overview
Embedded device boot is a layered relay race. To understand ARM architecture boot, first grasp the overall flow:
┌────────────────────────────────────────────────────────────┐
│ ARM Boot Sequence │
│ │
│ POR (Power-On Reset) │
│ │ │
│ ▼ │
│ ┌─────────┐ ── ROM (iROM) ── Stage 1 Bootloader │
│ │ BL1 │ (Hard-coded, vendor-wired) │
│ └────┬────┘ │
│ │ copy to SRAM │
│ ▼ │
│ ┌─────────┐ ── SRAM ── Stage 2 Bootloader │
│ │ BL2 │ (Modifiable, usually U-Boot SPL) │
│ └────┬────┘ │
│ │ jump to DRAM │
│ ▼ │
│ ┌─────────┐ ── DRAM ── U-Boot (full U-Boot) │
│ │ U-Boot │ Load Kernel + DTB │
│ └────┬────┘ │
│ │ bootm / booti │
│ ▼ │
│ ┌─────────┐ ── DRAM ── Linux Kernel │
│ │ Kernel │ Decompress/self-extract, enter ARM Linux │
│ └────┬────┘ │
│ │ start_kernel() │
│ ▼ │
│ ┌─────────┐ ── DRAM ── Init (PID 1) │
│ └─────────┘ │
└────────────────────────────────────────────────────────────┘2. ARM Exception Vector and Reset
ARM exception vector table (located at address 0x00000000 or 0xFFFF0000):
Offset Exception Handler
0x00 Reset reset_handler
0x04 Undefined Instruction und_handler
0x08 Software Interrupt (SWI) svc_handler
0x0C Prefetch Abort pabt_handler
0x10 Data Abort dabt_handler
0x14 Reserved —
0x18 IRQ (Interrupt) irq_handler
0x1C FIQ (Fast Interrupt) fiq_handler
On reset:
1. CPU enters SVC (Supervisor) mode
2. Disable interrupts (I and F bits in CPSR)
3. Set PC (Program Counter) to reset vector address
4. Start executing from reset_handler3. Minimal ARM Boot Assembly
Typical ARM boot header (start.S):
.section .text.boot
.globl _start
_start:
// 1. Enter SVC mode, disable interrupts
mrs r0, cpsr
bic r0, r0, #0x1F
orr r0, r0, #0xD3 // SVC mode + IRQ/FIQ disabled
msr cpsr, r0
// 2. Initialize stack pointer
ldr r0, =_stack_top
mov sp, r0
// 3. Clear BSS section
ldr r0, =__bss_start
ldr r1, =__bss_end
mov r2, #0
bss_clear_loop:
cmp r0, r1
strne r2, [r0], #4
bne bss_clear_loop
// 4. Enable I-Cache and D-Cache (if applicable)
mrc p15, 0, r0, c1, c0, 0 // Read SCTLR
orr r0, r0, #(1 << 12) // Enable I-Cache
// D-Cache: enable after MMU is set up
mcr p15, 0, r0, c1, c0, 0 // Write SCTLR
// 5. Jump to main()
bl main
// Infinite loop (should never reach here)
hang:
b hang
Comments