Updated WEEK03

This commit is contained in:
Kevin Thomas
2026-05-03 18:00:53 -04:00
parent 7c956ee514
commit d05687b79b
69 changed files with 2296 additions and 189 deletions
Binary file not shown.
Binary file not shown.
+275 -53
View File
@@ -130,8 +130,8 @@ Think of the bootrom like the BIOS in your computer - it's the first thing that
### What Does the Bootrom Do?
1. **Initialize Hardware**: Sets up clocks, resets peripherals
2. **Check Boot Sources**: Looks for valid firmware in flash
3. **Validate Firmware**: Checks for magic markers (IMAGE_DEF)
2. **Check Boot Sources (Discovery)**: Scans configured boot sources (for this course: flash) to find a candidate firmware image region.
3. **Validate Firmware (Validation)**: Verifies that candidate by finding IMAGE_DEF start/end markers and parsing the block.
4. **Configure Flash**: Sets up the XIP interface
5. **Jump to Your Code**: Reads the vector table and jumps to your reset handler
@@ -158,6 +158,54 @@ Here's what it looks like in the Pico SDK:
- `0xffffded3` = Start marker ("I'm a valid Pico binary!")
- `0xab123579` = End marker ("End of the header block")
### See This Exact Block in Your ELF (Commands + Real Output)
Use these commands to view the IMAGE_DEF bytes directly in the ELF:
```powershell
arm-none-eabi-objdump -s --start-address=0x1000013c --stop-address=0x10000150 build/0x0001_hello-world.elf
arm-none-eabi-objdump -s --start-address=0x10000130 --stop-address=0x10000154 build/0x0001_hello-world.elf
arm-none-eabi-gdb build/0x0001_hello-world.elf -ex "x/20bx 0x1000013c" -ex quit
```
Actual output from this lesson build:
```text
build/0x0001_hello-world.elf: file format elf32-littlearm
Contents of section .text:
1000013c 42012110 ff010000 b01b0000 793512ab B.!.........y5..
1000014c 4ff00000 O...
build/0x0001_hello-world.elf: file format elf32-littlearm
Contents of section .text:
10000130 a0010010 90a31ae7 d3deffff 42012110 ............B.!.
10000140 ff010000 b01b0000 793512ab 4ff00000 ........y5..O...
10000150 1e490860 .I.`
```
Command 1 explained (`--start-address=0x1000013c --stop-address=0x10000150`):
- Starts at `0x1000013c`, so it does **not** include the start marker at `0x10000138` (`d3deffff`).
- Shows IMAGE_DEF body fields and the end marker:
- `42012110` = `42 01 21 10` (item type/size + secure mode field)
- `ff010000` = last-item marker + size + pad
- `b01b0000` = next word in the block payload for this build
- `793512ab` = `PICOBIN_BLOCK_MARKER_END` (`0xab123579` in little-endian)
- `4ff00000` at `0x1000014c` is already the next instruction word after IMAGE_DEF.
Command 2 explained (`--start-address=0x10000130 --stop-address=0x10000154`):
- Starts earlier, so it captures context **and** both IMAGE_DEF markers.
- `a0010010 90a31ae7` = binary-info context before IMAGE_DEF.
- `d3deffff` at `0x10000138` = `PICOBIN_BLOCK_MARKER_START`.
- `793512ab` at `0x10000148` = `PICOBIN_BLOCK_MARKER_END`.
- `4ff00000 1e490860` = code words after the IMAGE_DEF block.
- This command proves the full block location for this build: `0x10000138` to `0x1000014b`.
Important: IMAGE_DEF offset can vary by build. In this build, the start marker `d3deffff`
is at `0x10000138` (not `0x1000013c`), so always search for the marker bytes instead of
assuming a fixed address.
> 📖 **Datasheet Reference:** Block markers are defined in Section 5.1.5.1 "Blocks" (p. 357): *"it must begin with the 4 byte magic header, PICOBIN_BLOCK_MARKER_START (0xffffded3)"* and *"it must end with the 4 byte magic footer, PICOBIN_BLOCK_MARKER_END (0xab123579)"*. The minimum Arm IMAGE_DEF is detailed in Section 5.9.5.1 (p. 429).
> ⚠️ **RP2350 vs RP2040 Key Difference:** Unlike the RP2040, the RP2350 does **not** require a checksummed "boot2" function at flash address 0. The RP2350 bootrom performs its own flash XIP setup. Instead, the RP2350 requires a valid IMAGE_DEF block **anywhere within the first 4 kB** of the image (Datasheet §5.9.5, p. 429: *"This must appear within the first 4 kB of a flash image"*; §5.2, p. 375: *"the main differences being the removal of a boot2 in the first 256 bytes of the image"*).
@@ -350,7 +398,7 @@ arm-none-eabi-gdb build\0x0001_hello-world.elf
**Connect to target:**
```gdb
(gdb) target remote :3333
(gdb) target extended-remote :3333
(gdb) monitor reset halt
```
@@ -383,7 +431,7 @@ Let's look at the first 4 entries of the vector table at `0x10000000`:
### Step 2: Understanding What We See
> 🔄 **REVIEW:** In Week 1, we saw `sp = 0x20081fc8` when stopped at `main`. That's *after* some stack was used during boot. Here we see the *initial* stack pointer before any code runs!
> 🔄 **REVIEW:** In Weeks 1-2, we saw both `sp = 0x20082000` at the clean breakpoint at `main` and lower values like `0x20081fc8` or `0x20081ff8` after additional stack activity. Here we are looking at the *initial* stack pointer from the vector table before any code runs.
Let's decode each value:
@@ -491,39 +539,39 @@ Let's look at more instructions to see the full picture:
(gdb) x/20i 0x1000015c
```
**You should see something like:**
**You should see:**
```
0x1000015c <_reset_handler>: mov.w r0, #3489660928 @ 0xd0000000
0x10000160 <_reset_handler+4>: ldr r0, [r0, #0]
0x10000162 <_reset_handler+6>:
cbz r0, 0x1000016a <hold_non_core0_in_bootrom+6>
0x10000164 <hold_non_core0_in_bootrom>: mov.w r0, #0
0x10000168 <hold_non_core0_in_bootrom+4>:
b.n 0x10000150 <_enter_vtable_in_r0>
0x1000016a <hold_non_core0_in_bootrom+6>:
add r4, pc, #52 @ (adr r4, 0x100001a0 <data_cpy_table>)
0x1000016c <hold_non_core0_in_bootrom+8>: ldmia r4!, {r1, r2, r3}
0x1000016e <hold_non_core0_in_bootrom+10>: cmp r1, #0
0x10000170 <hold_non_core0_in_bootrom+12>:
beq.n 0x10000178 <hold_non_core0_in_bootrom+20>
0x10000172 <hold_non_core0_in_bootrom+14>:
bl 0x1000019a <data_cpy>
0x10000176 <hold_non_core0_in_bootrom+18>:
b.n 0x1000016c <hold_non_core0_in_bootrom+8>
0x10000178 <hold_non_core0_in_bootrom+20>:
ldr r1, [pc, #84] @ (0x100001d0 <data_cpy_table+48>)
0x1000017a <hold_non_core0_in_bootrom+22>:
ldr r2, [pc, #88] @ (0x100001d4 <data_cpy_table+52>)
0x1000017c <hold_non_core0_in_bootrom+24>: movs r0, #0
0x1000017e <hold_non_core0_in_bootrom+26>:
b.n 0x10000182 <bss_fill_test>
0x10000180 <bss_fill_loop>: stmia r1!, {r0}
0x10000182 <bss_fill_test>: cmp r1, r2
0x10000184 <bss_fill_test+2>: bne.n 0x10000180 <bss_fill_loop>
0x10000186 <platform_entry>:
ldr r1, [pc, #80] @ (0x100001d8 <data_cpy_table+56>)
0x10000188 <platform_entry+2>: blx r1
0x1000015c <_reset_handler>: mov.w r0, #3489660928 @ 0xd0000000
0x10000160 <_reset_handler+4>: ldr r0, [r0, #0]
0x10000162 <_reset_handler+6>:
cbz r0, 0x1000016a <hold_non_core0_in_bootrom+6>
0x10000164 <hold_non_core0_in_bootrom>: mov.w r0, #0
0x10000168 <hold_non_core0_in_bootrom+4>:
b.n 0x10000150 <_enter_vtable_in_r0>
0x1000016a <hold_non_core0_in_bootrom+6>:
add r4, pc, #52 @ (adr r4, 0x100001a0 <data_cpy_table>)
0x1000016c <hold_non_core0_in_bootrom+8>: ldmia r4!, {r1, r2, r3}
0x1000016e <hold_non_core0_in_bootrom+10>: cmp r1, #0
0x10000170 <hold_non_core0_in_bootrom+12>:
beq.n 0x10000178 <hold_non_core0_in_bootrom+20>
0x10000172 <hold_non_core0_in_bootrom+14>:
bl 0x1000019a <data_cpy>
0x10000176 <hold_non_core0_in_bootrom+18>:
b.n 0x1000016c <hold_non_core0_in_bootrom+8>
0x10000178 <hold_non_core0_in_bootrom+20>:
ldr r1, [pc, #84] @ (0x100001d0 <data_cpy_table+48>)
0x1000017a <hold_non_core0_in_bootrom+22>:
ldr r2, [pc, #88] @ (0x100001d4 <data_cpy_table+52>)
0x1000017c <hold_non_core0_in_bootrom+24>: movs r0, #0
0x1000017e <hold_non_core0_in_bootrom+26>:
b.n 0x10000182 <bss_fill_test>
0x10000180 <bss_fill_loop>: stmia r1!, {r0}
0x10000182 <bss_fill_test>: cmp r1, r2
0x10000184 <bss_fill_test+2>: bne.n 0x10000180 <bss_fill_loop>
0x10000186 <platform_entry>:
ldr r1, [pc, #80] @ (0x100001d8 <data_cpy_table+56>)
0x10000188 <platform_entry+2>: blx r1
```
> 💡 **About GDB Label Offsets:** You may notice GDB shows instructions like `<hold_non_core0_in_bootrom+8>` for code that is clearly part of the data copy loop, not the core-parking function. This is **not** a GDB bug or "symbol snapping" — `hold_non_core0_in_bootrom` is a **real label** defined in the SDK's `crt0.S` (line 454). The `+8` offset simply means "8 bytes past that label." GDB always displays addresses relative to the nearest preceding symbol. The data copy code falls through from the `cbz` branch at the core check, landing right after the `hold_non_core0_in_bootrom` label, hence the offset.
@@ -540,22 +588,23 @@ The reset handler performs several phases:
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ PHASE 2: Data Copy (0x1000016a - 0x10000176)
│ PHASE 2: Data Copy Setup & Loop (0x1000016a - 0x10000176) │
│ - Set up the data_cpy_table pointer and load each copy triplet │
│ - Copy initialized variables from flash to RAM │
│ - Uses data_cpy_table for source/destination info │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ PHASE 3: BSS Clear (0x10000178 - 0x10000184)
│ PHASE 3: BSS Setup & Clear (0x10000178 - 0x10000184) │
│ - Load the BSS start/end addresses into r1 and r2 │
│ - GDB labels those literals as `data_cpy_table+48/+52` │
│ - Zero out all uninitialized global variables │
│ - C standard requires BSS to start at zero │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ PHASE 4: Runtime Init & Main (0x10000186+)
│ - Call runtime_init() for SDK setup
│ - Call __libc_init_array() for C++ constructors
│ - Finally call main()!
│ PHASE 4: Platform Entry Begins (0x10000186 - 0x10000188 shown)
│ - Load the runtime_init() pointer from the table
│ - Branch to runtime_init() with `blx r1`
│ - `main()` and `exit()` appear a few instructions later
└─────────────────────────────────────────────────────────────────┘
```
@@ -668,6 +717,8 @@ b.n 0x10000182 <bss_fill_test>
0x10000180 <bss_fill_loop>: stmia r1!, {r0}
```
The first two `ldr` instructions are still part of the **BSS clear setup**, even though GDB shows the source words as `data_cpy_table+48` and `data_cpy_table+52`. That label means the two literal words live in the same nearby constant block as the copy-table entries; it does **not** mean the code is still performing `.data` copies. At this point, `r1` becomes the BSS start address, `r2` becomes the BSS end address, and the loop beginning at `0x10000180` zeros that range.
### Understanding the Loop
```
@@ -1018,7 +1069,7 @@ Ghidra can visualize the call flow:
1. With `_reset_handler` selected, go to **Window → Function Call Graph**
2. This shows a visual graph of all function calls from the reset handler
3. You can see the path: `_reset_handler` `platform_entry``main`
3. You will see `_reset_handler` at the top with arrows going down to its four direct callees: `data_cpy`, `runtime_init`, `main`, and `exit`
### Comparing GDB and Ghidra for Boot Analysis
@@ -1156,21 +1207,18 @@ Ghidra can visualize the call flow:
- Is it a valid code address (starts with `0x1000...`)?
- What handler does it point to?
### Exercise 4: Find Your Main Function
### Exercise 4: Find Your Main Function and Trace Back
1. Use `info functions main` to find main
2. Examine 10 instructions at that address
3. Identify the first function call in main
4. What does that function do?
5. When stopped at main, examine `$lr` (link register)
6. What address is stored there?
7. Disassemble that address - what function is it?
8. This shows you where main was called from!
### Exercise 5: Trace Back from Main
1. When stopped at main, examine `$lr` (link register)
2. What address is stored there?
3. Disassemble that address - what function is it?
4. This shows you where main was called from!
### Exercise 6: Ghidra Boot Analysis
### Exercise 5: Ghidra Boot Analysis
1. In Ghidra, navigate to `_reset_handler`
2. Use **Window → Function Call Graph** to visualize the call tree
@@ -1398,6 +1446,180 @@ https://github.com/raspberrypi/pico-bootrom-rp2350
---
## 🔬 Part 17: Proving the Boot Sequence with objdump
Everything we have learned about the boot sequence can be proven directly from the compiled ELF binary using `arm-none-eabi-objdump`. The bootrom is not in your ELF (it is mask ROM burned into the chip at `0x00000000`), but everything your firmware provides — the vector table, the IMAGE_DEF, and the reset handler — lives in your ELF starting at `0x10000000`.
### Step 1: List All Sections
```bash
arm-none-eabi-objdump -h build/0x0001_hello-world.elf
```
Expected output (key sections):
```
Idx Name Size VMA LMA
0 .text 000019cc 10000000 10000000
3 .binary_info 0000002c 10001b20 10001b20
4 .ram_vector_table 00000110 20000000 20000000
6 .data 0000019c 20000110 10001b4c
```
> 💡 The Pico SDK merges `.vectors`, `.embedded_block`, and `.reset` all into `.text` at `0x10000000`. They are not separate named ELF sections — they are sub-regions inside `.text`.
### Step 2: Dump the First 0x150 Bytes of Flash — One Command, Zero Skips
```bash
arm-none-eabi-objdump -s --start-address=0x10000000 --stop-address=0x10000150 build/0x0001_hello-world.elf
```
Raw output from that command:
```
10000000 00200820 5d010010 1b010010 1d010010 . . ]...........
10000010 11010010 11010010 11010010 11010010 ................
10000020 11010010 11010010 11010010 11010010 ................
10000030 11010010 11010010 11010010 11010010 ................
10000040 11010010 11010010 11010010 11010010 ................
10000050 11010010 11010010 11010010 11010010 ................
10000060 11010010 11010010 11010010 11010010 ................
10000070 11010010 11010010 11010010 11010010 ................
10000080 11010010 11010010 11010010 11010010 ................
10000090 11010010 11010010 11010010 11010010 ................
100000a0 11010010 11010010 11010010 11010010 ................
100000b0 11010010 11010010 11010010 11010010 ................
100000c0 11010010 11010010 11010010 11010010 ................
100000d0 11010010 11010010 11010010 11010010 ................
100000e0 11010010 11010010 11010010 11010010 ................
100000f0 11010010 11010010 11010010 11010010 ................
10000100 11010010 11010010 11010010 11010010 ................
10000110 eff30580 103800be 00be00be 00be00be .....8..........
10000120 00be00be f2eb8871 201b0010 4c1b0010 .......q ...L...
10000130 a0010010 90a31ae7 d3deffff 42012110 ............B.!.
10000140 ff010000 b01b0000 793512ab ........y5..
```
Every address annotated, no skips:
#### 0x10000000 — Vector Table, Mandatory Entries
| Address | Raw Bytes (LE) | Decoded | What it is |
|---------|----------------|---------|------------|
| `0x10000000` | `00 20 08 20` | `0x20082000` | **Initial SP** — top of SCRATCH_Y RAM. Bootrom loads MSP from here before doing anything else. |
| `0x10000004` | `5d 01 00 10` | `0x1000015d` | **Reset_Handler** address with Thumb bit set. Strip bit 0 → real address `0x1000015c`. Bootrom jumps here. |
| `0x10000008` | `1b 01 00 10` | `0x1000011b` | **NMI** handler address (Thumb, → `0x1000011a`). |
| `0x1000000c` | `1d 01 00 10` | `0x1000011d` | **HardFault** handler address (Thumb, → `0x1000011c`). |
#### 0x100000100x1000010f — Vector Table, IRQ Slots (all 52 external IRQs)
```
10000010 11010010 11010010 ...(repeats through 0x1000010f)...
```
Every 4-byte word here is `11 01 00 10` = pointer `0x10000111`.
That is the **default IRQ handler** address with Thumb bit set (→ `0x10000110`).
The RP2350 Cortex-M33 has 16 system vectors (offsets 0x000x3f) plus up to 52
external IRQ vectors (offsets 0x400xff = addresses `0x10000040``0x1000010f`).
Every IRQ the application does not register gets this default handler pointer.
This block is 240 bytes (`0x10000010` to `0x1000010f`) of nothing but that one
repeated pointer.
#### 0x100001100x10000127 — Default IRQ Handler Code
```
10000110 eff30580 103800be 00be00be 00be00be
10000120 00be00be f2eb8871
```
| Address | Bytes | ARM Thumb-2 Instruction | What it does |
|---------|-------|-------------------------|--------------|
| `0x10000110` | `ef f3 05 80` | `MRS r0, IPSR` | Read the Interrupt Program Status Register into r0. The low 9 bits = the active vector number. |
| `0x10000114` | `10 38` | `SUBS r0, #16` | Vector 16 = IRQ0, so subtract 16 to convert vector number → IRQ index. |
| `0x10000116` | `00 be` | `BKPT #0` | Software breakpoint. If a debugger is attached, it stops here and you can inspect r0 to see which IRQ fired. If no debugger is attached, the CPU enters a fault loop and the chip hangs. |
| `0x10000118``0x10000127` | `00 be` ×12 | `BKPT #0` repeating | Alignment padding to the next 4-byte boundary. |
This is the **entire** default IRQ handler. It is intentionally minimal: if your
code triggers an IRQ you did not register, it crashes visibly instead of silently.
#### 0x100001280x1000013b — Binary Info Pointer Table
```
10000120 201b0010 4c1b0010
10000130 a0010010 90a31ae7
```
| Address | Bytes (LE) | Decoded Value | What it is |
|---------|------------|---------------|------------|
| `0x10000128` | `20 1b 00 10` | `0x10001b20` | Pointer to **start** of `.binary_info` data section in flash. |
| `0x1000012c` | `4c 1b 00 10` | `0x10001b4c` | Pointer to **end** of `.binary_info` data section in flash. |
| `0x10000130` | `a0 01 00 10` | `0x100001a0` | Pointer to `binary_info_callback` function. |
| `0x10000134` | `90 a3 1a e7` | (magic marker) | `BINARY_INFO_MARKER_END` — marks the end of this pointer table. |
`picotool` reads this table to extract the program name, version string, URL,
and GPIO pin map from any compiled binary without running it.
#### 0x100001380x1000014c — IMAGE_DEF Block (this build)
```
10000130 a0010010 90a31ae7 d3deffff 42012110
10000140 ff010000 b01b0000 793512ab 4ff00000
```
| Address | Bytes | What it is |
|---------|-------|------------|
| `0x10000138` | `d3 de ff ff` | `PICOBIN_BLOCK_MARKER_START` — the bootrom scans flash for this exact 4-byte sequence to locate the IMAGE_DEF. |
| `0x1000013c` | `42 01 21 10` | IMAGE_DEF content (image type, flags, version). |
| `0x10000140` | `ff 01 00 00` | IMAGE_DEF content (continuation). |
| `0x10000144` | `b0 1b 00 00` | IMAGE_DEF content (continuation). |
| `0x10000148` | `79 35 12 ab` | `PICOBIN_BLOCK_MARKER_END` — bootrom stops scanning here. |
The IMAGE_DEF sits at `0x10000138``0x1000014b` in this build,
well within the 4 KB scan window the bootrom uses (Datasheet §5.9.5, p. 429).
#### Full Flash Map: 0x100000000x1000015c
```
0x100000000x1000000f Vector Table: mandatory entries (SP, Reset, NMI, HardFault)
0x100000100x1000010f Vector Table: 52 external IRQ slots → all point to default handler
0x100001100x10000127 Default IRQ handler code (MRS / SUBS / BKPT)
0x100001280x10000137 Binary info pointer table (start / end / callback / magic end)
0x100001380x1000014b IMAGE_DEF block (d3 de ff ff ... 79 35 12 ab)
0x100001500x1000015b (padding / alignment)
0x1000015c Reset_Handler (_reset_handler in crt0.S) ← bootrom jumps here
```
### Step 4: Confirmed Boot Sequence (proven from ELF)
```
┌─────────────────────────────────────────────────────────────────┐
│ PROVEN BOOT SEQUENCE (0x0001_hello-world) │
├─────────────────────────────────────────────────────────────────┤
│ 1. Bootrom reads 0x10000000 │
│ → SP = 0x20082000 (offset +0x00 of vector table) │
│ → RST = 0x1000015d (offset +0x04, Thumb → 0x1000015c) │
├─────────────────────────────────────────────────────────────────┤
│ 2. Bootrom scans first 4 kB for IMAGE_DEF │
│ → Found at 0x10000138 (this build) │
│ → Start marker: d3 de ff ff │
│ → End marker: 79 35 12 ab │
├─────────────────────────────────────────────────────────────────┤
│ 3. Bootrom jumps to reset handler at 0x1000015c │
│ → _reset_handler (crt0.S) runs │
│ → Checks CPUID — Core 1 sent back to bootrom │
│ → Core 0: .data copied, .bss zeroed, platform_entry called │
├─────────────────────────────────────────────────────────────────┤
│ 4. platform_entry calls runtime_init → main → exit │
└─────────────────────────────────────────────────────────────────┘
```
> 📖 **Datasheet References:**
> - §5.1.5.1 (p. 357): Block markers `0xffffded3` (start) and `0xab123579` (end)
> - §5.9.5 (p. 429): IMAGE_DEF must appear within first 4 kB of flash image
> - §5.9.5.1 (p. 429): Bootrom enters via reset handler at vector table offset +4
---
**Remember:** Understanding the boot process is fundamental to embedded systems work. Whether you're debugging a system that won't start, reverse engineering firmware, or building secure boot chains, this knowledge is essential!
Happy exploring! 🔍
+6 -6
View File
@@ -24,7 +24,7 @@
<text x="60" y="167" class="dim">Cortex-M33 wakes, execution at 0x00000000 (Bootrom)</text>
<!-- Arrow -->
<text x="600" y="198" text-anchor="middle" class="grn"></text>
<text x="600" y="200" text-anchor="middle" class="grn"></text>
<!-- Step 2 -->
<rect x="40" y="208" width="1120" height="70" rx="6" fill="#12121a" stroke="#ffaa00" stroke-width="2"/>
@@ -33,7 +33,7 @@
<text x="60" y="265" class="dim">32KB on-chip ROM — finds IMAGE_DEF at 0x10000000</text>
<!-- Arrow -->
<text x="600" y="296" text-anchor="middle" class="grn"></text>
<text x="600" y="298" text-anchor="middle" class="grn"></text>
<!-- Step 3 -->
<rect x="40" y="306" width="1120" height="70" rx="6" fill="#12121a" stroke="#ffaa00" stroke-width="2"/>
@@ -42,7 +42,7 @@
<text x="60" y="363" class="dim">Bootrom configures flash interface &amp; XIP (no boot2 on RP2350)</text>
<!-- Arrow -->
<text x="600" y="394" text-anchor="middle" class="grn"></text>
<text x="600" y="396" text-anchor="middle" class="grn"></text>
<!-- Step 4 -->
<rect x="40" y="404" width="1120" height="90" rx="6" fill="#12121a" stroke="#ffaa00" stroke-width="2"/>
@@ -58,9 +58,9 @@
<rect x="40" y="524" width="1120" height="110" rx="6" fill="#12121a" stroke="#ffaa00" stroke-width="2"/>
<text x="60" y="551" class="amb">STEP 5</text>
<text x="220" y="551" class="txt">C Runtime Startup (crt0.S)</text>
<text x="60" y="583" class="dim">Copy .data from flash -> RAM</text>
<text x="60" y="608" class="dim">Zero .bss section</text>
<text x="60" y="633" class="dim">Call runtime_init() -> main()</text>
<text x="60" y="579" class="dim">Copy .data from flash -> RAM</text>
<text x="60" y="603" class="dim">Zero .bss section</text>
<text x="60" y="627" class="dim">Call runtime_init() -> main()</text>
<!-- Bottom summary -->
<rect x="40" y="660" width="1120" height="110" rx="6" fill="#12121a" stroke="#ffaa00" stroke-width="2"/>
+1 -1
View File
@@ -76,5 +76,5 @@
<text x="640" y="682" class="txt">PendSV, SysTick all use:</text>
<rect x="660" y="700" width="480" height="42" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
<text x="680" y="728" class="red">bkpt 0x0000</text>
<text x="880" y="728" class="dim"><- stops debugger</text>
<text x="880" y="728" class="dim">&lt;- stops debugger</text>
</svg>
+3 -3
View File
@@ -60,19 +60,19 @@
<text x="170" y="543" text-anchor="middle" class="amb">Core Check</text>
<text x="170" y="569" text-anchor="middle" class="dim">CPUID == 0?</text>
<text x="300" y="553" class="grn">-></text>
<text x="303" y="553" text-anchor="middle" class="grn">-></text>
<rect x="325" y="513" width="200" height="70" rx="6" fill="#0a0a0f" stroke="#00d4ff" stroke-width="2"/>
<text x="425" y="543" text-anchor="middle" class="cyn">Data Copy</text>
<text x="425" y="569" text-anchor="middle" class="dim">flash -> RAM</text>
<text x="545" y="553" class="grn">-></text>
<text x="548" y="553" text-anchor="middle" class="grn">-></text>
<rect x="570" y="513" width="200" height="70" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
<text x="670" y="543" text-anchor="middle" class="grn">BSS Clear</text>
<text x="670" y="569" text-anchor="middle" class="dim">zero globals</text>
<text x="790" y="553" class="grn">-></text>
<text x="793" y="553" text-anchor="middle" class="grn">-></text>
<rect x="815" y="513" width="305" height="70" rx="6" fill="#0a0a0f" stroke="#ff0040" stroke-width="2"/>
<text x="967" y="543" text-anchor="middle" class="red">Platform Entry</text>
+3 -3
View File
@@ -49,13 +49,13 @@
<text x="210" y="478" text-anchor="middle" class="amb">runtime_init()</text>
<text x="210" y="508" text-anchor="middle" class="dim">SDK setup</text>
<text x="385" y="488" class="grn">-></text>
<text x="390" y="488" text-anchor="middle" class="grn">-></text>
<rect x="420" y="443" width="300" height="80" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
<text x="570" y="478" text-anchor="middle" class="grn">main()</text>
<text x="570" y="508" text-anchor="middle" class="dim">YOUR CODE</text>
<text x="745" y="488" class="grn">-></text>
<text x="750" y="488" text-anchor="middle" class="grn">-></text>
<rect x="780" y="443" width="300" height="80" rx="6" fill="#0a0a0f" stroke="#ff0040" stroke-width="2"/>
<text x="930" y="478" text-anchor="middle" class="red">exit()</text>
@@ -76,7 +76,7 @@
<text x="640" y="677" class="txt">Then:</text>
<rect x="660" y="700" width="480" height="42" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
<text x="680" y="728" class="red">bkpt 0x0000</text>
<text x="900" y="728" class="dim"><- infinite halt</text>
<text x="900" y="728" class="dim">&lt;- infinite halt</text>
<text x="640" y="760" class="dim">Should never be reached!</text>
</svg>
+3 -3
View File
@@ -68,19 +68,19 @@
<text x="170" y="603" text-anchor="middle" class="grn">Bootrom</text>
<text x="170" y="629" text-anchor="middle" class="dim">immutable</text>
<text x="298" y="613" class="amb">-></text>
<text x="300" y="613" text-anchor="middle" class="amb">-></text>
<rect x="320" y="573" width="220" height="70" rx="6" fill="#0a0a0f" stroke="#00d4ff" stroke-width="2"/>
<text x="430" y="603" text-anchor="middle" class="cyn">Verify Sig</text>
<text x="430" y="629" text-anchor="middle" class="dim">IMAGE_DEF</text>
<text x="558" y="613" class="amb">-></text>
<text x="560" y="613" text-anchor="middle" class="amb">-></text>
<rect x="580" y="573" width="220" height="70" rx="6" fill="#0a0a0f" stroke="#ffaa00" stroke-width="2"/>
<text x="690" y="603" text-anchor="middle" class="amb">Verify App</text>
<text x="690" y="629" text-anchor="middle" class="dim">signature</text>
<text x="818" y="613" class="amb">-></text>
<text x="820" y="613" text-anchor="middle" class="amb">-></text>
<rect x="840" y="573" width="280" height="70" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
<text x="980" y="603" text-anchor="middle" class="grn">Boot!</text>