mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-05-16 13:19:14 +02:00
Updated WEEK03
This commit is contained in:
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"cmake.sourceDirectory": "C:/Users/assem.KEVINTHOMAS/OneDrive/Documents/Embedded-Hacking/0x0001_hello-world"
|
||||
}
|
||||
+4
-2
@@ -261,9 +261,11 @@ These are the most frequent mistakes. Avoid them.
|
||||
|
||||
---
|
||||
|
||||
## ⏰ Time Limit
|
||||
## ⏰ Deadline & Submission
|
||||
|
||||
You have **4 hours** to complete this examination.
|
||||
- This is a **take-home final project**. See the course syllabus for the due date.
|
||||
- Submit all deliverables as a single ZIP file or as specified by your instructor.
|
||||
- Late submissions: see syllabus late work policy.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+312
-82
@@ -70,14 +70,17 @@ Each of these steps has a corresponding piece of code. Let's explore them all!
|
||||
│ STEP 2: Bootrom Executes (32KB on-chip ROM) │
|
||||
│ - This code is burned into the chip - can't be changed! │
|
||||
│ - It looks for valid firmware in flash memory │
|
||||
│ - It checks for the IMAGE_DEF structure at 0x10000000 │
|
||||
│ - It scans the first 4 kB of the image for a valid IMAGE_DEF │
|
||||
│ (Datasheet §4.1, p. 338: 32KB ROM; §5.9.5, p. 429: IMAGE_DEF) │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ STEP 3: Boot Stage 2 (boot2) │
|
||||
│ - Configures the flash interface for fast reading │
|
||||
│ STEP 3: Flash XIP Setup (bootrom-managed) │
|
||||
│ - The bootrom configures the flash interface automatically │
|
||||
│ - Sets up XIP (Execute In Place) mode │
|
||||
│ - Returns control to the bootrom │
|
||||
│ - NOTE: Unlike RP2040, there is NO separate boot2 in flash! │
|
||||
│ (Datasheet §5.2, p. 375: "removal of a boot2 in the first │
|
||||
│ 256 bytes of the image") │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
@@ -119,8 +122,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
|
||||
|
||||
@@ -131,22 +134,70 @@ The bootrom looks for a special marker in your firmware called **IMAGE_DEF**. Th
|
||||
Here's what it looks like in the Pico SDK:
|
||||
|
||||
```assembly
|
||||
.section .picobin_block, "a" // placed in flash
|
||||
.word 0xffffded3 // PICOBIN_BLOCK_MARKER_START ← ROM looks for this!
|
||||
.byte 0x42 // PICOBIN_BLOCK_ITEM_1BS_IMAGE_TYPE
|
||||
.byte 0x1 // item is 1 word in size
|
||||
.hword 0b0001000000100001 // SECURE mode (0x1021)
|
||||
.byte 0xff // PICOBIN_BLOCK_ITEM_2BS_LAST
|
||||
.hword 0x0001 // item is 1 word in size
|
||||
.byte 0x0 // pad
|
||||
.word 0x0 // relative pointer to next block (0 = loop to self)
|
||||
.word 0xab123579 // PICOBIN_BLOCK_MARKER_END
|
||||
.section .picobin_block, "a" // placed in flash
|
||||
.word 0xffffded3 // PICOBIN_BLOCK_MARKER_START ← ROM looks for this!
|
||||
.byte 0x42 // PICOBIN_BLOCK_ITEM_1BS_IMAGE_TYPE
|
||||
.byte 0x1 // item is 1 word in size
|
||||
.hword 0b0001000000100001 // SECURE mode (0x1021)
|
||||
.byte 0xff // PICOBIN_BLOCK_ITEM_2BS_LAST
|
||||
.hword 0x0001 // item is 1 word in size
|
||||
.byte 0x0 // pad
|
||||
.word 0x0 // relative pointer to next block (0 = loop to self)
|
||||
.word 0xab123579 // PICOBIN_BLOCK_MARKER_END
|
||||
```
|
||||
|
||||
**The magic numbers:**
|
||||
- `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.
|
||||
|
||||
---
|
||||
|
||||
## 📚 Part 3: Understanding XIP (Execute In Place)
|
||||
@@ -327,7 +378,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
|
||||
```
|
||||
|
||||
@@ -360,7 +411,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:
|
||||
|
||||
@@ -466,39 +517,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
|
||||
```
|
||||
|
||||
### Step 7: Understanding the Startup Phases
|
||||
@@ -513,22 +564,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 │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -562,7 +614,8 @@ The data copy table contains entries that describe what to copy where. Let's exa
|
||||
|
||||
```
|
||||
0x100001a0 <data_cpy_table>: 0x10001b4c 0x20000110 0x200002ac 0x10001ce8
|
||||
...
|
||||
0x100001b0 <data_cpy_table+16>: 0x20080000 0x20080000 0x10001ce8 0x20081000
|
||||
0x100001c0 <data_cpy_table+32>: 0x20081000 0x00000000 0x00004770 0xe000ed08
|
||||
```
|
||||
|
||||
The data_cpy_table contains multiple entries. Each entry has three values:
|
||||
@@ -641,6 +694,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
|
||||
|
||||
```
|
||||
@@ -762,7 +817,8 @@ Let's verify we understand the boot process by setting a breakpoint at main:
|
||||
**You should see:**
|
||||
|
||||
```
|
||||
Breakpoint 1 at 0x10000234: file 0x0001_hello-world.c, line 5.
|
||||
Breakpoint 1 at 0x10000234: file C:/Users/flare-vm/Desktop/Embedded-Hacking-main/0x0001_hello-world/0x0001_hello-world.c, line 5.
|
||||
Note: automatically using hardware breakpoints for read-only addresses.
|
||||
```
|
||||
|
||||
**Now continue:**
|
||||
@@ -776,8 +832,10 @@ Breakpoint 1 at 0x10000234: file 0x0001_hello-world.c, line 5.
|
||||
```
|
||||
Continuing.
|
||||
|
||||
Breakpoint 1, main () at 0x0001_hello-world.c:5
|
||||
5 stdio_init_all();
|
||||
Thread 1 "rp2350.cm0" hit Breakpoint 1, main ()
|
||||
at C:/Users/flare-vm/Desktop/Embedded-Hacking-main/0x0001_hello-world/0x0001_hello-world.c:5
|
||||
5 stdio_init_all();
|
||||
(gdb)
|
||||
```
|
||||
|
||||
🎉 We've traced the entire boot process from power-on to `main()`!
|
||||
@@ -822,7 +880,7 @@ GDB doesn't know this is data, not code! It tries to disassemble it as Thumb ins
|
||||
```
|
||||
|
||||
```
|
||||
0x10000138 <__binary_info_header_end>: udf #211 @ 0xd3
|
||||
0x10000138 <__binary_info_header_end>: udf #211 @ 0xd3
|
||||
```
|
||||
|
||||
That's not real code - it's the magic number `0xffffded3` being misinterpreted!
|
||||
@@ -884,6 +942,7 @@ While GDB is excellent for dynamic analysis (watching code execute), Ghidra exce
|
||||
1000000d 01 ?? 01h
|
||||
1000000e 00 ?? 00h
|
||||
1000000f 10 ?? 10h
|
||||
...
|
||||
```
|
||||
|
||||
> 💡 **Notice:** Ghidra shows the vector table data as individual bytes by default. You can see it has labeled the start as `__vectors`, `__flash_binary_start`, `__VECTOR_TABLE`, and `__logical_binary_start`. The arrows (like `? -> 1000015d`) show that Ghidra recognizes these bytes as pointers to code addresses! To see the data formatted as 32-bit addresses instead of bytes, you can right-click and retype the data.
|
||||
@@ -953,9 +1012,9 @@ Let's find how the boot code eventually calls `main()`:
|
||||
|
||||
| Location | Type | Label |
|
||||
| ------------------------- | ---- | ------------------ |
|
||||
| `platform_entry+6` | CALL | `blx r1` (to main) |
|
||||
| `1000018c` | CALL | `blx r1` (to main) |
|
||||
|
||||
4. Double-click on the reference to jump to `platform_entry`
|
||||
4. Double-click on the reference to jump to `1000018c`
|
||||
|
||||
### Step 19: Examine Platform Entry
|
||||
|
||||
@@ -991,7 +1050,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
|
||||
|
||||
@@ -1023,8 +1082,8 @@ Ghidra can visualize the call flow:
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ 2. BOOTROM │
|
||||
│ - Initializes hardware │
|
||||
│ - Finds IMAGE_DEF at 0x10000000 │
|
||||
│ - Runs boot2 to configure flash │
|
||||
│ - Configures flash XIP (no separate boot2 on RP2350) │
|
||||
│ - Finds IMAGE_DEF within first 4 kB of flash image │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ 3. VECTOR TABLE (0x10000000) │
|
||||
│ - Reads SP from offset 0x00 → 0x20082000 │
|
||||
@@ -1129,21 +1188,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
|
||||
@@ -1221,9 +1277,7 @@ Understanding the boot process is critical for both attackers and defenders. Kno
|
||||
│ ↓ │
|
||||
│ Verify IMAGE_DEF signature │
|
||||
│ ↓ │
|
||||
│ Verify boot2 signature │
|
||||
│ ↓ │
|
||||
│ Verify application signature │
|
||||
│ Verify application image signature │
|
||||
│ ↓ │
|
||||
│ If all valid: Jump to reset handler │
|
||||
│ If any invalid: Refuse to boot │
|
||||
@@ -1342,9 +1396,11 @@ https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf
|
||||
### Pico SDK Source Code
|
||||
|
||||
The startup code lives in:
|
||||
- `crt0.S` - Main startup assembly
|
||||
- `memmap_default.ld` - Default linker script
|
||||
- `boot2_generic_03h.S` - Second stage bootloader
|
||||
- `crt0.S` - Main startup assembly (vector table at `.section .vectors`, reset handler, data copy, BSS clear, platform_entry)
|
||||
- `memmap_default.ld` - Default linker script (section ordering: `.vectors` -> `.binary_info_header` -> `.embedded_block` -> `.reset`)
|
||||
- `embedded_start_block.inc.S` - IMAGE_DEF block (replaces RP2040's `boot2_generic_03h.S`)
|
||||
|
||||
> ⚠️ **Note:** The RP2040 used a `boot2_generic_03h.S` second-stage bootloader occupying the first 256 bytes of flash. The RP2350 eliminated this; the bootrom handles flash XIP setup directly. The SDK still includes a `boot2` mechanism for compatibility, but it is **not** placed at flash address 0 - it is embedded in the data copy table and executed from the stack during startup.
|
||||
|
||||
### Bootrom Source
|
||||
|
||||
@@ -1353,6 +1409,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`). |
|
||||
|
||||
#### 0x10000010–0x1000010f — 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 0x00–0x3f) plus up to 52
|
||||
external IRQ vectors (offsets 0x40–0xff = 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.
|
||||
|
||||
#### 0x10000110–0x10000127 — 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.
|
||||
|
||||
#### 0x10000128–0x1000013b — 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.
|
||||
|
||||
#### 0x10000138–0x1000014c — 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: 0x10000000–0x1000015c
|
||||
|
||||
```
|
||||
0x10000000–0x1000000f Vector Table: mandatory entries (SP, Reset, NMI, HardFault)
|
||||
0x10000010–0x1000010f Vector Table: 52 external IRQ slots → all point to default handler
|
||||
0x10000110–0x10000127 Default IRQ handler code (MRS / SUBS / BKPT)
|
||||
0x10000128–0x10000137 Binary info pointer table (start / end / callback / magic end)
|
||||
0x10000138–0x1000014b IMAGE_DEF block (d3 de ff ff ... 79 35 12 ab)
|
||||
0x10000150–0x1000015b (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! 🔍
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
|
||||
<style>
|
||||
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
|
||||
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
|
||||
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
|
||||
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
|
||||
.dim{font:20px 'Courier New',monospace;fill:#888}
|
||||
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
|
||||
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
|
||||
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
|
||||
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
|
||||
.badge{stroke:#00ff41;rx:14}
|
||||
</style>
|
||||
<rect class="bg" width="1200" height="800"/>
|
||||
|
||||
<!-- Background grid decoration -->
|
||||
<g opacity="0.06">
|
||||
<line x1="0" y1="100" x2="1200" y2="100" stroke="#00ff41" stroke-width="1"/>
|
||||
<line x1="0" y1="200" x2="1200" y2="200" stroke="#00ff41" stroke-width="1"/>
|
||||
<line x1="0" y1="300" x2="1200" y2="300" stroke="#00ff41" stroke-width="1"/>
|
||||
<line x1="0" y1="400" x2="1200" y2="400" stroke="#00ff41" stroke-width="1"/>
|
||||
<line x1="0" y1="500" x2="1200" y2="500" stroke="#00ff41" stroke-width="1"/>
|
||||
<line x1="0" y1="600" x2="1200" y2="600" stroke="#00ff41" stroke-width="1"/>
|
||||
<line x1="0" y1="700" x2="1200" y2="700" stroke="#00ff41" stroke-width="1"/>
|
||||
<line x1="200" y1="0" x2="200" y2="800" stroke="#00ff41" stroke-width="1"/>
|
||||
<line x1="400" y1="0" x2="400" y2="800" stroke="#00ff41" stroke-width="1"/>
|
||||
<line x1="600" y1="0" x2="600" y2="800" stroke="#00ff41" stroke-width="1"/>
|
||||
<line x1="800" y1="0" x2="800" y2="800" stroke="#00ff41" stroke-width="1"/>
|
||||
<line x1="1000" y1="0" x2="1000" y2="800" stroke="#00ff41" stroke-width="1"/>
|
||||
</g>
|
||||
|
||||
<!-- Hex rain decoration -->
|
||||
<g opacity="0.04" font-family="'Courier New',monospace" font-size="14" fill="#00ff41">
|
||||
<text x="50" y="80">4F 70 65 6E 4F 43 44</text>
|
||||
<text x="900" y="120">10 00 02 34 08 B5 01</text>
|
||||
<text x="150" y="180">47 44 42 20 52 45 56</text>
|
||||
<text x="800" y="240">20 08 20 00 FF AA 00</text>
|
||||
<text x="80" y="350">52 50 32 33 35 30 00</text>
|
||||
<text x="950" y="380">0A 0A 0F 12 12 1A 1A</text>
|
||||
<text x="100" y="520">41 52 4D 76 38 2D 4D</text>
|
||||
<text x="870" y="560">00 FF 41 00 D4 FF 88</text>
|
||||
<text x="60" y="680">47 48 49 44 52 41 00</text>
|
||||
<text x="920" y="720">FF 00 40 C0 C0 C0 00</text>
|
||||
</g>
|
||||
|
||||
<!-- Corner accents -->
|
||||
<polyline points="30,30 30,80 80,80" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
|
||||
<polyline points="1170,30 1170,80 1120,80" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
|
||||
<polyline points="30,770 30,720 80,720" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
|
||||
<polyline points="1170,770 1170,720 1120,720" fill="none" stroke="#00ff41" stroke-width="2" opacity="0.3"/>
|
||||
|
||||
<!-- Top accent line -->
|
||||
<rect x="100" y="140" width="1000" height="2" fill="#00ff41" opacity="0.4"/>
|
||||
|
||||
<!-- Course Title -->
|
||||
<text x="600" y="210" text-anchor="middle" font-family="'Courier New',monospace" font-size="56" font-weight="bold" fill="#00ff41">Embedded Systems</text>
|
||||
<text x="600" y="278" text-anchor="middle" font-family="'Courier New',monospace" font-size="56" font-weight="bold" fill="#00ff41">Reverse Engineering</text>
|
||||
|
||||
<!-- Divider -->
|
||||
<rect x="300" y="310" width="600" height="2" fill="#00d4ff" opacity="0.6"/>
|
||||
|
||||
<!-- Week Number -->
|
||||
<text x="600" y="380" text-anchor="middle" font-family="'Courier New',monospace" font-size="42" font-weight="bold" fill="#00d4ff">// WEEK 03</text>
|
||||
|
||||
<!-- Week Topic -->
|
||||
<text x="600" y="440" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">Embedded System Analysis:</text>
|
||||
<text x="600" y="478" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">Understanding the RP2350 Architecture</text>
|
||||
<text x="600" y="516" text-anchor="middle" font-family="'Courier New',monospace" font-size="28" fill="#c0c0c0">w/ Comprehensive Firmware Analysis</text>
|
||||
|
||||
<!-- Bottom accent line -->
|
||||
<rect x="100" y="570" width="1000" height="2" fill="#00ff41" opacity="0.4"/>
|
||||
|
||||
<!-- University -->
|
||||
<text x="600" y="635" text-anchor="middle" font-family="'Courier New',monospace" font-size="36" font-weight="bold" fill="#ffaa00">George Mason University</text>
|
||||
|
||||
<!-- Bottom badge -->
|
||||
<rect x="400" y="670" width="400" height="40" rx="20" fill="none" stroke="#00ff41" stroke-width="1.5" opacity="0.5"/>
|
||||
<text x="600" y="697" text-anchor="middle" font-family="'Courier New',monospace" font-size="20" fill="#00ff41" opacity="0.7">RP2350 // ARM Cortex-M33</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
@@ -0,0 +1,70 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
|
||||
<style>
|
||||
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
|
||||
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
|
||||
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
|
||||
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
|
||||
.dim{font:20px 'Courier New',monospace;fill:#888}
|
||||
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
|
||||
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
|
||||
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
|
||||
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
|
||||
.badge{stroke:#00ff41;rx:14}
|
||||
</style>
|
||||
<rect class="bg" width="1200" height="800"/>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="600" y="52" text-anchor="middle" class="title">RP2350 Boot Sequence</text>
|
||||
<text x="600" y="88" text-anchor="middle" class="dim">Power-On to main() — 5 Steps</text>
|
||||
|
||||
<!-- Step 1 -->
|
||||
<rect x="40" y="110" width="1120" height="70" rx="6" fill="#12121a" stroke="#ffaa00" stroke-width="2"/>
|
||||
<text x="60" y="137" class="amb">STEP 1</text>
|
||||
<text x="220" y="137" class="txt">Power On</text>
|
||||
<text x="60" y="167" class="dim">Cortex-M33 wakes, execution at 0x00000000 (Bootrom)</text>
|
||||
|
||||
<!-- Arrow -->
|
||||
<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"/>
|
||||
<text x="60" y="235" class="amb">STEP 2</text>
|
||||
<text x="220" y="235" class="txt">Bootrom Executes</text>
|
||||
<text x="60" y="265" class="dim">32KB on-chip ROM — finds IMAGE_DEF at 0x10000000</text>
|
||||
|
||||
<!-- Arrow -->
|
||||
<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"/>
|
||||
<text x="60" y="333" class="amb">STEP 3</text>
|
||||
<text x="220" y="333" class="txt">Flash XIP Setup (bootrom-managed)</text>
|
||||
<text x="60" y="363" class="dim">Bootrom configures flash interface & XIP (no boot2 on RP2350)</text>
|
||||
|
||||
<!-- Arrow -->
|
||||
<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"/>
|
||||
<text x="60" y="431" class="amb">STEP 4</text>
|
||||
<text x="220" y="431" class="txt">Vector Table & Reset Handler</text>
|
||||
<text x="60" y="463" class="dim">Reads SP from offset 0x00 -> 0x20082000</text>
|
||||
<text x="60" y="489" class="dim">Reads Reset Handler from 0x04 -> 0x1000015d</text>
|
||||
|
||||
<!-- Arrow -->
|
||||
<text x="600" y="514" text-anchor="middle" class="grn">▼</text>
|
||||
|
||||
<!-- Step 5 -->
|
||||
<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="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"/>
|
||||
<text x="60" y="695" class="sub">Key Insight</text>
|
||||
<text x="60" y="730" class="txt">Your main() is the LAST thing to run.</text>
|
||||
<text x="60" y="760" class="txt">All 5 steps must complete first!</text>
|
||||
</svg>
|
||||
@@ -0,0 +1,84 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
|
||||
<style>
|
||||
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
|
||||
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
|
||||
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
|
||||
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
|
||||
.dim{font:20px 'Courier New',monospace;fill:#888}
|
||||
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
|
||||
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
|
||||
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
|
||||
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
|
||||
.badge{stroke:#00ff41;rx:14}
|
||||
</style>
|
||||
<rect class="bg" width="1200" height="800"/>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="600" y="52" text-anchor="middle" class="title">The Bootrom</text>
|
||||
<text x="600" y="88" text-anchor="middle" class="dim">32KB Factory-Programmed ROM — Where It All Begins</text>
|
||||
|
||||
<!-- Left Panel: Properties -->
|
||||
<rect x="40" y="110" width="540" height="340" rx="8" class="pnl"/>
|
||||
<text x="60" y="148" class="sub">Bootrom Properties</text>
|
||||
|
||||
<rect x="60" y="170" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="75" y="198" class="txt">Size</text>
|
||||
<text x="340" y="198" class="grn">32 KB</text>
|
||||
|
||||
<rect x="60" y="222" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="75" y="250" class="txt">Location</text>
|
||||
<text x="340" y="250" class="cyn">0x00000000</text>
|
||||
|
||||
<rect x="60" y="274" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="75" y="302" class="txt">Modifiable?</text>
|
||||
<text x="340" y="302" class="red">NO — mask ROM</text>
|
||||
|
||||
<rect x="60" y="326" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="75" y="354" class="txt">Purpose</text>
|
||||
<text x="340" y="354" class="amb">Boot the chip</text>
|
||||
|
||||
<text x="60" y="420" class="dim">Burned into silicon at factory</text>
|
||||
<text x="60" y="445" class="dim">Like BIOS in your computer</text>
|
||||
|
||||
<!-- Right Panel: What It Does -->
|
||||
<rect x="620" y="110" width="540" height="340" rx="8" class="pnl"/>
|
||||
<text x="640" y="148" class="sub">What It Does</text>
|
||||
|
||||
<rect x="640" y="170" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="655" y="198" class="grn">1.</text>
|
||||
<text x="700" y="198" class="txt">Initialize hardware</text>
|
||||
|
||||
<rect x="640" y="222" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="655" y="250" class="grn">2.</text>
|
||||
<text x="700" y="250" class="txt">Check boot sources</text>
|
||||
|
||||
<rect x="640" y="274" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="655" y="302" class="grn">3.</text>
|
||||
<text x="700" y="302" class="txt">Validate IMAGE_DEF</text>
|
||||
|
||||
<rect x="640" y="326" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="655" y="354" class="grn">4.</text>
|
||||
<text x="700" y="354" class="txt">Configure flash</text>
|
||||
|
||||
<rect x="640" y="378" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="655" y="406" class="grn">5.</text>
|
||||
<text x="700" y="406" class="txt">Jump to your code</text>
|
||||
|
||||
<!-- Bottom Panel: IMAGE_DEF -->
|
||||
<rect x="40" y="475" width="1120" height="295" rx="8" class="pnl"/>
|
||||
<text x="60" y="513" class="sub">IMAGE_DEF — Magic Markers</text>
|
||||
<text x="60" y="548" class="dim">Bootrom looks for these to validate firmware</text>
|
||||
|
||||
<rect x="60" y="565" width="1080" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="80" y="598" class="grn">Start Marker</text>
|
||||
<text x="380" y="598" class="cyn">0xFFFFDED3</text>
|
||||
<text x="680" y="598" class="dim">"I'm a valid Pico binary!"</text>
|
||||
|
||||
<rect x="60" y="625" width="1080" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="80" y="658" class="grn">End Marker</text>
|
||||
<text x="380" y="658" class="cyn">0xAB123579</text>
|
||||
<text x="680" y="658" class="dim">"End of header block"</text>
|
||||
|
||||
<text x="60" y="718" class="txt">Bootrom reads flash at 0x10000000,</text>
|
||||
<text x="60" y="748" class="txt">finds these markers, then boots.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,74 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
|
||||
<style>
|
||||
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
|
||||
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
|
||||
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
|
||||
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
|
||||
.dim{font:20px 'Courier New',monospace;fill:#888}
|
||||
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
|
||||
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
|
||||
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
|
||||
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
|
||||
.badge{stroke:#00ff41;rx:14}
|
||||
</style>
|
||||
<rect class="bg" width="1200" height="800"/>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="600" y="52" text-anchor="middle" class="title">XIP — Execute In Place</text>
|
||||
<text x="600" y="88" text-anchor="middle" class="dim">Run Code Directly from Flash — No Copy Needed</text>
|
||||
|
||||
<!-- Left Panel: Analogy -->
|
||||
<rect x="40" y="110" width="540" height="220" rx="8" class="pnl"/>
|
||||
<text x="60" y="148" class="sub">Book Analogy</text>
|
||||
|
||||
<rect x="60" y="168" width="500" height="60" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
|
||||
<text x="75" y="195" class="red">Without XIP</text>
|
||||
<text x="75" y="220" class="dim">Photocopy every page, read copy</text>
|
||||
|
||||
<rect x="60" y="240" width="500" height="60" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
|
||||
<text x="75" y="267" class="grn">With XIP</text>
|
||||
<text x="75" y="292" class="dim">Read directly from the book!</text>
|
||||
|
||||
<!-- Right Panel: Advantages -->
|
||||
<rect x="620" y="110" width="540" height="220" rx="8" class="pnl"/>
|
||||
<text x="640" y="148" class="sub">Why Use XIP?</text>
|
||||
|
||||
<rect x="640" y="168" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="655" y="196" class="grn">Saves RAM</text>
|
||||
<text x="900" y="196" class="dim">Code stays in flash</text>
|
||||
|
||||
<rect x="640" y="220" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="655" y="248" class="grn">Faster Boot</text>
|
||||
<text x="900" y="248" class="dim">No bulk copy needed</text>
|
||||
|
||||
<rect x="640" y="272" width="500" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="655" y="300" class="grn">Simpler</text>
|
||||
<text x="900" y="300" class="dim">Less memory mgmt</text>
|
||||
|
||||
<!-- Bottom Panel: Flash Layout at 0x10000000 -->
|
||||
<rect x="40" y="355" width="1120" height="415" rx="8" class="pnl"/>
|
||||
<text x="60" y="393" class="sub">XIP Flash Region at 0x10000000</text>
|
||||
|
||||
<!-- Vector Table block -->
|
||||
<rect x="60" y="415" width="1080" height="80" rx="4" fill="#0f1a0f" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="80" y="445" class="grn">Vector Table</text>
|
||||
<text x="80" y="475" class="dim">SP at offset 0x00 | Reset Handler at offset 0x04 | Exception handlers...</text>
|
||||
|
||||
<!-- Your Code block -->
|
||||
<rect x="60" y="510" width="1080" height="80" rx="4" fill="#0a0a0f" stroke="#00d4ff" stroke-width="2"/>
|
||||
<text x="80" y="540" class="cyn">Your Code</text>
|
||||
<text x="80" y="570" class="dim">_reset_handler | main() | other functions</text>
|
||||
|
||||
<!-- Read-Only Data block -->
|
||||
<rect x="60" y="605" width="1080" height="80" rx="4" fill="#0a0a0f" stroke="#ffaa00" stroke-width="2"/>
|
||||
<text x="80" y="635" class="amb">Read-Only Data</text>
|
||||
<text x="80" y="665" class="dim">Strings like "hello, world" | constant values</text>
|
||||
|
||||
<!-- Address labels -->
|
||||
<text x="1040" y="445" class="dim" text-anchor="end">0x10000000</text>
|
||||
<text x="1040" y="540" class="dim" text-anchor="end">0x100001xx</text>
|
||||
<text x="1040" y="635" class="dim" text-anchor="end">0x10001xxx</text>
|
||||
|
||||
<text x="60" y="730" class="txt">CPU fetches instructions directly</text>
|
||||
<text x="60" y="760" class="txt">from flash via XIP cache.</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
@@ -0,0 +1,80 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
|
||||
<style>
|
||||
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
|
||||
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
|
||||
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
|
||||
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
|
||||
.dim{font:20px 'Courier New',monospace;fill:#888}
|
||||
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
|
||||
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
|
||||
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
|
||||
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
|
||||
.badge{stroke:#00ff41;rx:14}
|
||||
</style>
|
||||
<rect class="bg" width="1200" height="800"/>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="600" y="52" text-anchor="middle" class="title">The Vector Table</text>
|
||||
<text x="600" y="88" text-anchor="middle" class="dim">CPU's Instruction Manual at 0x10000000</text>
|
||||
|
||||
<!-- Main Panel -->
|
||||
<rect x="40" y="110" width="1120" height="440" rx="8" class="pnl"/>
|
||||
<text x="60" y="148" class="sub">Vector Table Layout</text>
|
||||
|
||||
<!-- Header row -->
|
||||
<rect x="60" y="168" width="1080" height="42" rx="4" fill="#1a1a2e"/>
|
||||
<text x="80" y="196" class="cyn">Offset</text>
|
||||
<text x="220" y="196" class="cyn">Address</text>
|
||||
<text x="440" y="196" class="cyn">Value</text>
|
||||
<text x="680" y="196" class="cyn">Meaning</text>
|
||||
|
||||
<!-- Row 0x00 -->
|
||||
<rect x="60" y="220" width="1080" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="80" y="252" class="grn">0x00</text>
|
||||
<text x="220" y="252" class="txt">0x10000000</text>
|
||||
<text x="440" y="252" class="grn">0x20082000</text>
|
||||
<text x="680" y="252" class="txt">Initial SP</text>
|
||||
|
||||
<!-- Row 0x04 -->
|
||||
<rect x="60" y="280" width="1080" height="50" rx="4" fill="#0a0a0f" stroke="#00d4ff" stroke-width="2"/>
|
||||
<text x="80" y="312" class="cyn">0x04</text>
|
||||
<text x="220" y="312" class="txt">0x10000004</text>
|
||||
<text x="440" y="312" class="cyn">0x1000015D</text>
|
||||
<text x="680" y="312" class="txt">Reset Handler</text>
|
||||
|
||||
<!-- Row 0x08 -->
|
||||
<rect x="60" y="340" width="1080" height="50" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="80" y="372" class="dim">0x08</text>
|
||||
<text x="220" y="372" class="txt">0x10000008</text>
|
||||
<text x="440" y="372" class="txt">0x1000011B</text>
|
||||
<text x="680" y="372" class="txt">NMI Handler</text>
|
||||
|
||||
<!-- Row 0x0C -->
|
||||
<rect x="60" y="400" width="1080" height="50" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="80" y="432" class="dim">0x0C</text>
|
||||
<text x="220" y="432" class="txt">0x1000000C</text>
|
||||
<text x="440" y="432" class="txt">0x1000011D</text>
|
||||
<text x="680" y="432" class="txt">HardFault Handler</text>
|
||||
|
||||
<!-- GDB command -->
|
||||
<rect x="60" y="470" width="1080" height="50" rx="4" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
|
||||
<text x="80" y="502" class="amb">GDB:</text>
|
||||
<text x="180" y="502" class="txt">x/4x 0x10000000</text>
|
||||
|
||||
<!-- Bottom Panel: What happens -->
|
||||
<rect x="40" y="575" width="540" height="195" rx="8" class="pnl"/>
|
||||
<text x="60" y="613" class="sub">On Power-On</text>
|
||||
<text x="60" y="650" class="txt">1. CPU reads SP from 0x00</text>
|
||||
<text x="60" y="682" class="txt">2. Sets SP = 0x20082000</text>
|
||||
<text x="60" y="714" class="txt">3. Reads Reset from 0x04</text>
|
||||
<text x="60" y="746" class="txt">4. Jumps to 0x1000015C</text>
|
||||
|
||||
<!-- Bottom Right: Handlers -->
|
||||
<rect x="620" y="575" width="540" height="195" rx="8" class="pnl"/>
|
||||
<text x="640" y="613" class="sub">Default Handlers</text>
|
||||
<text x="640" y="650" class="txt">NMI, HardFault, SVCall,</text>
|
||||
<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>
|
||||
</svg>
|
||||
@@ -0,0 +1,70 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
|
||||
<style>
|
||||
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
|
||||
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
|
||||
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
|
||||
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
|
||||
.dim{font:20px 'Courier New',monospace;fill:#888}
|
||||
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
|
||||
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
|
||||
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
|
||||
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
|
||||
.badge{stroke:#00ff41;rx:14}
|
||||
</style>
|
||||
<rect class="bg" width="1200" height="800"/>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="600" y="52" text-anchor="middle" class="title">Thumb Mode Addressing</text>
|
||||
<text x="600" y="88" text-anchor="middle" class="dim">Why Addresses End in Odd Numbers</text>
|
||||
|
||||
<!-- Top Panel: The Rule -->
|
||||
<rect x="40" y="110" width="1120" height="200" rx="8" class="pnl"/>
|
||||
<text x="60" y="148" class="sub">The LSB Rule</text>
|
||||
<text x="60" y="185" class="txt">ARM Cortex-M uses the Least Significant</text>
|
||||
<text x="60" y="215" class="txt">Bit (LSB) to indicate instruction mode:</text>
|
||||
|
||||
<!-- LSB = 1 -->
|
||||
<rect x="60" y="240" width="520" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="80" y="272" class="grn">LSB = 1 (odd)</text>
|
||||
<text x="370" y="272" class="txt">Thumb mode</text>
|
||||
|
||||
<!-- LSB = 0 -->
|
||||
<rect x="620" y="240" width="520" height="50" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
|
||||
<text x="640" y="272" class="red">LSB = 0 (even)</text>
|
||||
<text x="940" y="272" class="dim">ARM mode</text>
|
||||
|
||||
<!-- Middle Panel: Example -->
|
||||
<rect x="40" y="335" width="1120" height="210" rx="8" class="pnl"/>
|
||||
<text x="60" y="373" class="sub">Reset Handler Example</text>
|
||||
|
||||
<text x="60" y="415" class="txt">Vector table stores:</text>
|
||||
<text x="460" y="415" class="cyn">0x1000015D</text>
|
||||
|
||||
<text x="60" y="460" class="txt">Actual code address:</text>
|
||||
<text x="460" y="460" class="grn">0x1000015C</text>
|
||||
|
||||
<text x="60" y="505" class="txt">The +1 means:</text>
|
||||
<text x="460" y="505" class="amb">"Use Thumb mode"</text>
|
||||
|
||||
<!-- Bottom: GDB vs Ghidra -->
|
||||
<rect x="40" y="570" width="540" height="200" rx="8" class="pnl"/>
|
||||
<text x="60" y="608" class="sub">GDB Shows</text>
|
||||
<rect x="60" y="625" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#00d4ff" stroke-width="1"/>
|
||||
<text x="80" y="657" class="cyn">0x1000015D</text>
|
||||
<text x="320" y="657" class="dim">with Thumb bit</text>
|
||||
|
||||
<rect x="60" y="685" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="80" y="717" class="txt">Vector table raw value</text>
|
||||
|
||||
<!-- Ghidra -->
|
||||
<rect x="620" y="570" width="540" height="200" rx="8" class="pnl"/>
|
||||
<text x="640" y="608" class="sub">Ghidra Shows</text>
|
||||
<rect x="640" y="625" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
|
||||
<text x="660" y="657" class="grn">0x1000015C</text>
|
||||
<text x="900" y="657" class="dim">actual address</text>
|
||||
|
||||
<rect x="640" y="685" width="500" height="50" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="660" y="717" class="txt">Real instruction location</text>
|
||||
|
||||
<text x="600" y="757" text-anchor="middle" class="amb">Both are correct — just displayed differently!</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1,69 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
|
||||
<style>
|
||||
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
|
||||
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
|
||||
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
|
||||
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
|
||||
.dim{font:20px 'Courier New',monospace;fill:#888}
|
||||
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
|
||||
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
|
||||
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
|
||||
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
|
||||
.badge{stroke:#00ff41;rx:14}
|
||||
</style>
|
||||
<rect class="bg" width="1200" height="800"/>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="600" y="52" text-anchor="middle" class="title">Linker Script Memory Map</text>
|
||||
<text x="600" y="88" text-anchor="middle" class="dim">memmap_default.ld — Where Everything Lives</text>
|
||||
|
||||
<!-- Main Panel: Memory Regions -->
|
||||
<rect x="40" y="110" width="1120" height="380" rx="8" class="pnl"/>
|
||||
<text x="60" y="148" class="sub">Memory Regions</text>
|
||||
|
||||
<!-- Flash -->
|
||||
<rect x="60" y="168" width="1080" height="60" rx="4" fill="#0f1a0f" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="80" y="198" class="grn">Flash (XIP)</text>
|
||||
<text x="380" y="198" class="cyn">0x10000000</text>
|
||||
<text x="640" y="198" class="txt">varies</text>
|
||||
<text x="820" y="198" class="dim">Your code (read-only)</text>
|
||||
|
||||
<!-- RAM -->
|
||||
<rect x="60" y="240" width="1080" height="60" rx="4" fill="#0a0a1f" stroke="#00d4ff" stroke-width="2"/>
|
||||
<text x="80" y="270" class="cyn">RAM</text>
|
||||
<text x="380" y="270" class="cyn">0x20000000</text>
|
||||
<text x="640" y="270" class="txt">512 KB</text>
|
||||
<text x="820" y="270" class="dim">Main RAM (r/w)</text>
|
||||
|
||||
<!-- SCRATCH_X -->
|
||||
<rect x="60" y="312" width="1080" height="60" rx="4" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
|
||||
<text x="80" y="342" class="amb">SCRATCH_X</text>
|
||||
<text x="380" y="342" class="cyn">0x20080000</text>
|
||||
<text x="640" y="342" class="txt">4 KB</text>
|
||||
<text x="820" y="342" class="dim">Core 0 scratch (HW: SRAM8)</text>
|
||||
|
||||
<!-- SCRATCH_Y -->
|
||||
<rect x="60" y="384" width="1080" height="60" rx="4" fill="#1a0a0a" stroke="#ff0040" stroke-width="2"/>
|
||||
<text x="80" y="414" class="red">SCRATCH_Y</text>
|
||||
<text x="380" y="414" class="cyn">0x20081000</text>
|
||||
<text x="640" y="414" class="txt">4 KB</text>
|
||||
<text x="820" y="414" class="dim">Core 0 stack! (HW: SRAM9)</text>
|
||||
|
||||
<!-- Bottom Panel: Stack Calculation -->
|
||||
<rect x="40" y="515" width="1120" height="255" rx="8" class="pnl"/>
|
||||
<text x="60" y="553" class="sub">Stack Pointer Calculation</text>
|
||||
|
||||
<text x="60" y="593" class="txt">__StackTop = ORIGIN(SCRATCH_Y)</text>
|
||||
<text x="60" y="623" class="txt"> + LENGTH(SCRATCH_Y)</text>
|
||||
|
||||
<rect x="60" y="650" width="1080" height="100" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="80" y="682" class="amb">ORIGIN</text>
|
||||
<text x="260" y="682" class="cyn">0x20081000</text>
|
||||
|
||||
<text x="500" y="682" class="amb">+ LENGTH</text>
|
||||
<text x="700" y="682" class="cyn">0x1000</text>
|
||||
<text x="830" y="682" class="dim">(4 KB)</text>
|
||||
|
||||
<text x="80" y="728" class="grn">= __StackTop = 0x20082000</text>
|
||||
<text x="680" y="728" class="dim"><- matches vector table!</text>
|
||||
</svg>
|
||||
@@ -0,0 +1,87 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
|
||||
<style>
|
||||
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
|
||||
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
|
||||
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
|
||||
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
|
||||
.dim{font:20px 'Courier New',monospace;fill:#888}
|
||||
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
|
||||
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
|
||||
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
|
||||
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
|
||||
.badge{stroke:#00ff41;rx:14}
|
||||
</style>
|
||||
<rect class="bg" width="1200" height="800"/>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="600" y="52" text-anchor="middle" class="title">Reset Handler — 4 Phases</text>
|
||||
<text x="600" y="88" text-anchor="middle" class="dim">_reset_handler at 0x1000015C</text>
|
||||
|
||||
<!-- Phase 1 -->
|
||||
<rect x="40" y="110" width="555" height="150" rx="8" class="pnl" stroke="#ffaa00" stroke-width="2"/>
|
||||
<text x="60" y="143" class="amb">Phase 1: Core Check</text>
|
||||
<text x="60" y="170" class="dim">0x1000015C — 0x10000168</text>
|
||||
<rect x="60" y="185" width="515" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="75" y="213" class="txt">mov r0, #0xD0000000</text>
|
||||
<text x="75" y="248" class="dim">Read CPUID -> Core 0 continues</text>
|
||||
|
||||
<!-- Phase 2 -->
|
||||
<rect x="625" y="110" width="535" height="150" rx="8" class="pnl" stroke="#00d4ff" stroke-width="2"/>
|
||||
<text x="645" y="143" class="cyn">Phase 2: Data Copy</text>
|
||||
<text x="645" y="170" class="dim">0x1000016A — 0x10000176</text>
|
||||
<rect x="645" y="185" width="495" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="660" y="213" class="txt">ldmia r4!, {r1,r2,r3}</text>
|
||||
<text x="645" y="248" class="dim">Copy .data from flash -> RAM</text>
|
||||
|
||||
<!-- Phase 3 -->
|
||||
<rect x="40" y="280" width="555" height="150" rx="8" class="pnl" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="60" y="313" class="grn">Phase 3: BSS Clear</text>
|
||||
<text x="60" y="340" class="dim">0x10000178 — 0x10000184</text>
|
||||
<rect x="60" y="355" width="515" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="75" y="383" class="txt">stmia r1!, {r0}</text>
|
||||
<text x="340" y="383" class="dim">r0 = 0</text>
|
||||
<text x="60" y="418" class="dim">Zero all uninitialized globals</text>
|
||||
|
||||
<!-- Phase 4 -->
|
||||
<rect x="625" y="280" width="535" height="150" rx="8" class="pnl" stroke="#ff0040" stroke-width="2"/>
|
||||
<text x="645" y="313" class="red">Phase 4: Platform Entry</text>
|
||||
<text x="645" y="340" class="dim">0x10000186+</text>
|
||||
<rect x="645" y="355" width="495" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="660" y="383" class="txt">blx r1</text>
|
||||
<text x="800" y="383" class="dim">-> main()</text>
|
||||
<text x="645" y="418" class="dim">runtime_init -> main -> exit</text>
|
||||
|
||||
<!-- Bottom: Flow Diagram -->
|
||||
<rect x="40" y="455" width="1120" height="315" rx="8" class="pnl"/>
|
||||
<text x="60" y="493" class="sub">Execution Flow</text>
|
||||
|
||||
<!-- Step boxes -->
|
||||
<rect x="60" y="513" width="220" height="70" rx="6" fill="#0a0a0f" stroke="#ffaa00" stroke-width="2"/>
|
||||
<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="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="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="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>
|
||||
<text x="967" y="569" text-anchor="middle" class="dim">-> main()!</text>
|
||||
|
||||
<!-- Dual core note -->
|
||||
<rect x="60" y="610" width="1080" height="150" rx="6" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
|
||||
<text x="80" y="645" class="amb">Why check cores?</text>
|
||||
<text x="80" y="680" class="txt">RP2350 has 2 cores.</text>
|
||||
<text x="80" y="710" class="txt">Only Core 0 runs startup.</text>
|
||||
<text x="80" y="740" class="dim">Core 1 returns to bootrom and waits.</text>
|
||||
</svg>
|
||||
@@ -0,0 +1,93 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
|
||||
<style>
|
||||
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
|
||||
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
|
||||
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
|
||||
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
|
||||
.dim{font:20px 'Courier New',monospace;fill:#888}
|
||||
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
|
||||
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
|
||||
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
|
||||
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
|
||||
.badge{stroke:#00ff41;rx:14}
|
||||
</style>
|
||||
<rect class="bg" width="1200" height="800"/>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="600" y="52" text-anchor="middle" class="title">Data Copy & BSS Clear</text>
|
||||
<text x="600" y="88" text-anchor="middle" class="dim">Initializing RAM Before main() Can Run</text>
|
||||
|
||||
<!-- Left Panel: Data Copy -->
|
||||
<rect x="40" y="110" width="555" height="420" rx="8" class="pnl" stroke="#00d4ff" stroke-width="2"/>
|
||||
<text x="60" y="148" class="cyn">Phase 2: Data Copy</text>
|
||||
<text x="60" y="178" class="dim">Copy initialized variables flash -> RAM</text>
|
||||
|
||||
<text x="60" y="218" class="txt">C code:</text>
|
||||
<rect x="60" y="230" width="515" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="75" y="258" class="amb">int counter = 42;</text>
|
||||
|
||||
<text x="60" y="300" class="txt">Value 42 stored in flash</text>
|
||||
<text x="60" y="330" class="txt">but variables live in RAM!</text>
|
||||
|
||||
<!-- Flash -> RAM diagram -->
|
||||
<rect x="60" y="358" width="210" height="60" rx="4" fill="#0f1a0f" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="165" y="395" text-anchor="middle" class="grn">Flash</text>
|
||||
|
||||
<text x="290" y="395" class="amb">-></text>
|
||||
|
||||
<rect x="320" y="358" width="210" height="60" rx="4" fill="#0a0a1f" stroke="#00d4ff" stroke-width="2"/>
|
||||
<text x="425" y="395" text-anchor="middle" class="cyn">RAM</text>
|
||||
|
||||
<!-- data_cpy_table -->
|
||||
<text x="60" y="448" class="dim">data_cpy_table has entries:</text>
|
||||
<rect x="60" y="458" width="515" height="55" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="75" y="482" class="dim">src: 0x10001B4C (flash)</text>
|
||||
<text x="75" y="507" class="dim">dst: 0x20000110 (RAM)</text>
|
||||
|
||||
<!-- Right Panel: BSS Clear -->
|
||||
<rect x="625" y="110" width="535" height="420" rx="8" class="pnl" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="645" y="148" class="grn">Phase 3: BSS Clear</text>
|
||||
<text x="645" y="178" class="dim">Zero uninitialized global variables</text>
|
||||
|
||||
<text x="645" y="218" class="txt">C code:</text>
|
||||
<rect x="645" y="230" width="495" height="42" rx="4" fill="#0a0a0f" stroke="#1a1a2e"/>
|
||||
<text x="660" y="258" class="amb">int my_counter;</text>
|
||||
|
||||
<text x="645" y="300" class="txt">C standard requires</text>
|
||||
<text x="645" y="330" class="txt">this to start at zero.</text>
|
||||
|
||||
<!-- BSS loop diagram -->
|
||||
<rect x="645" y="358" width="495" height="110" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
|
||||
<text x="665" y="388" class="txt">r1 = BSS start</text>
|
||||
<text x="665" y="418" class="txt">r2 = BSS end</text>
|
||||
<text x="665" y="448" class="txt">r0 = 0</text>
|
||||
|
||||
<text x="645" y="498" class="dim">Loop: store 0, advance r1</text>
|
||||
<text x="645" y="524" class="dim">Until r1 == r2 -> done!</text>
|
||||
|
||||
<!-- Bottom Panel: Assembly -->
|
||||
<rect x="40" y="555" width="1120" height="215" rx="8" class="pnl"/>
|
||||
<text x="60" y="593" class="sub">Key Assembly Instructions</text>
|
||||
|
||||
<!-- Data Copy ASM -->
|
||||
<rect x="60" y="610" width="530" height="42" rx="4" fill="#0a0a0f" stroke="#00d4ff" stroke-width="1"/>
|
||||
<text x="75" y="638" class="cyn">ldmia r4!, {r1,r2,r3}</text>
|
||||
|
||||
<text x="60" y="672" class="dim">Load source, dest, end from table</text>
|
||||
|
||||
<rect x="60" y="690" width="530" height="42" rx="4" fill="#0a0a0f" stroke="#00d4ff" stroke-width="1"/>
|
||||
<text x="75" y="718" class="cyn">bl data_cpy</text>
|
||||
|
||||
<text x="60" y="750" class="dim">Copy word-by-word until done</text>
|
||||
|
||||
<!-- BSS Clear ASM -->
|
||||
<rect x="630" y="610" width="510" height="42" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
|
||||
<text x="645" y="638" class="grn">movs r0, #0</text>
|
||||
|
||||
<text x="630" y="672" class="dim">Load zero into r0</text>
|
||||
|
||||
<rect x="630" y="690" width="510" height="42" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
|
||||
<text x="645" y="718" class="grn">stmia r1!, {r0}</text>
|
||||
|
||||
<text x="630" y="750" class="dim">Store zero, advance pointer</text>
|
||||
</svg>
|
||||
@@ -0,0 +1,82 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
|
||||
<style>
|
||||
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
|
||||
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
|
||||
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
|
||||
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
|
||||
.dim{font:20px 'Courier New',monospace;fill:#888}
|
||||
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
|
||||
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
|
||||
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
|
||||
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
|
||||
.badge{stroke:#00ff41;rx:14}
|
||||
</style>
|
||||
<rect class="bg" width="1200" height="800"/>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="600" y="52" text-anchor="middle" class="title">Platform Entry -> main()</text>
|
||||
<text x="600" y="88" text-anchor="middle" class="dim">The Final Step — 3 Function Calls at 0x10000186</text>
|
||||
|
||||
<!-- Top Panel: Assembly -->
|
||||
<rect x="40" y="110" width="1120" height="250" rx="8" class="pnl"/>
|
||||
<text x="60" y="148" class="sub">platform_entry Assembly</text>
|
||||
|
||||
<rect x="60" y="168" width="1080" height="42" rx="4" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
|
||||
<text x="80" y="196" class="amb">0x10000186</text>
|
||||
<text x="310" y="196" class="txt">ldr r1, [DAT]</text>
|
||||
<text x="640" y="196" class="dim">-> load runtime_init addr</text>
|
||||
|
||||
<rect x="60" y="218" width="1080" height="42" rx="4" fill="#0a0a0f" stroke="#ffaa00" stroke-width="1"/>
|
||||
<text x="80" y="246" class="amb">0x10000188</text>
|
||||
<text x="310" y="246" class="txt">blx r1</text>
|
||||
<text x="640" y="246" class="cyn">-> call runtime_init()</text>
|
||||
|
||||
<rect x="60" y="268" width="1080" height="42" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="80" y="296" class="grn">0x1000018C</text>
|
||||
<text x="310" y="296" class="txt">blx r1</text>
|
||||
<text x="640" y="296" class="grn">-> call main()</text>
|
||||
|
||||
<rect x="60" y="318" width="1080" height="42" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
|
||||
<text x="80" y="346" class="red">0x10000190</text>
|
||||
<text x="310" y="346" class="txt">blx r1</text>
|
||||
<text x="640" y="346" class="red">-> call exit()</text>
|
||||
|
||||
<!-- Middle: Flow boxes -->
|
||||
<rect x="40" y="385" width="1120" height="160" rx="8" class="pnl"/>
|
||||
<text x="60" y="423" class="sub">Call Sequence</text>
|
||||
|
||||
<rect x="60" y="443" width="300" height="80" rx="6" fill="#0a0a0f" stroke="#ffaa00" stroke-width="2"/>
|
||||
<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="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="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>
|
||||
<text x="930" y="508" text-anchor="middle" class="dim">cleanup</text>
|
||||
|
||||
<!-- Bottom Panel: Details -->
|
||||
<rect x="40" y="570" width="540" height="200" rx="8" class="pnl"/>
|
||||
<text x="60" y="608" class="sub">runtime_init()</text>
|
||||
<text x="60" y="645" class="txt">Initializes SDK systems:</text>
|
||||
<text x="60" y="677" class="dim">• Clock configuration</text>
|
||||
<text x="60" y="705" class="dim">• GPIO setup</text>
|
||||
<text x="60" y="733" class="dim">• C++ constructor calls</text>
|
||||
<text x="60" y="761" class="dim">• Peripheral initialization</text>
|
||||
|
||||
<rect x="620" y="570" width="540" height="200" rx="8" class="pnl"/>
|
||||
<text x="640" y="608" class="sub">After main() Returns</text>
|
||||
<text x="640" y="645" class="txt">exit() handles cleanup.</text>
|
||||
<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="640" y="760" class="dim">Should never be reached!</text>
|
||||
</svg>
|
||||
@@ -0,0 +1,92 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800">
|
||||
<style>
|
||||
.bg{fill:#0a0a0f}.pnl{fill:#12121a;stroke:#1a1a2e}.hdr{fill:#12121a}
|
||||
.title{font:bold 42px 'Courier New',monospace;fill:#00ff41}
|
||||
.sub{font:bold 28px 'Courier New',monospace;fill:#00d4ff}
|
||||
.txt{font:24px 'Courier New',monospace;fill:#c0c0c0}
|
||||
.dim{font:20px 'Courier New',monospace;fill:#888}
|
||||
.grn{font:bold 24px 'Courier New',monospace;fill:#00ff41}
|
||||
.red{font:bold 24px 'Courier New',monospace;fill:#ff0040}
|
||||
.cyn{font:bold 24px 'Courier New',monospace;fill:#00d4ff}
|
||||
.amb{font:bold 24px 'Courier New',monospace;fill:#ffaa00}
|
||||
.badge{stroke:#00ff41;rx:14}
|
||||
</style>
|
||||
<rect class="bg" width="1200" height="800"/>
|
||||
|
||||
<!-- Title -->
|
||||
<text x="600" y="52" text-anchor="middle" class="title">Secure Boot & Attack Vectors</text>
|
||||
<text x="600" y="88" text-anchor="middle" class="dim">Why Boot Sequence Knowledge Matters for Security</text>
|
||||
|
||||
<!-- Left Panel: Attack Scenarios -->
|
||||
<rect x="40" y="110" width="555" height="380" rx="8" class="pnl" stroke="#ff0040" stroke-width="2"/>
|
||||
<text x="60" y="148" class="red">Attack Scenarios</text>
|
||||
|
||||
<rect x="60" y="168" width="515" height="60" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
|
||||
<text x="75" y="193" class="red">Firmware Replacement</text>
|
||||
<text x="75" y="218" class="dim">Replace flash with malicious code</text>
|
||||
|
||||
<rect x="60" y="238" width="515" height="60" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
|
||||
<text x="75" y="263" class="red">Vector Table Hijack</text>
|
||||
<text x="75" y="288" class="dim">Modify reset handler address</text>
|
||||
|
||||
<rect x="60" y="308" width="515" height="60" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
|
||||
<text x="75" y="333" class="red">Debug Port Attack</text>
|
||||
<text x="75" y="358" class="dim">SWD/JTAG to dump or inject code</text>
|
||||
|
||||
<rect x="60" y="378" width="515" height="60" rx="4" fill="#0a0a0f" stroke="#ff0040" stroke-width="1"/>
|
||||
<text x="75" y="403" class="red">Startup Code Modification</text>
|
||||
<text x="75" y="428" class="dim">Change crt0 data copy / BSS init</text>
|
||||
|
||||
<text x="60" y="472" class="amb">Physical access = game over</text>
|
||||
|
||||
<!-- Right Panel: Defense Strategies -->
|
||||
<rect x="625" y="110" width="535" height="380" rx="8" class="pnl" stroke="#00ff41" stroke-width="2"/>
|
||||
<text x="645" y="148" class="grn">Defense Strategies</text>
|
||||
|
||||
<rect x="645" y="168" width="495" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
|
||||
<text x="660" y="200" class="grn">1. Secure Boot</text>
|
||||
|
||||
<rect x="645" y="228" width="495" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
|
||||
<text x="660" y="260" class="grn">2. Debug Port Lock</text>
|
||||
|
||||
<rect x="645" y="288" width="495" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
|
||||
<text x="660" y="320" class="grn">3. Flash Read Protect</text>
|
||||
|
||||
<rect x="645" y="348" width="495" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
|
||||
<text x="660" y="380" class="grn">4. MPU Configuration</text>
|
||||
|
||||
<rect x="645" y="408" width="495" height="50" rx="4" fill="#0a0a0f" stroke="#00ff41" stroke-width="1"/>
|
||||
<text x="660" y="440" class="grn">5. Integrity Checks</text>
|
||||
|
||||
<text x="645" y="478" class="amb">Defense in depth!</text>
|
||||
|
||||
<!-- Bottom Panel: Secure Boot Flow -->
|
||||
<rect x="40" y="515" width="1120" height="255" rx="8" class="pnl"/>
|
||||
<text x="60" y="553" class="sub">Secure Boot Chain</text>
|
||||
|
||||
<rect x="60" y="573" width="220" height="70" rx="6" fill="#0a0a0f" stroke="#00ff41" stroke-width="2"/>
|
||||
<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="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="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="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>
|
||||
<text x="980" y="629" text-anchor="middle" class="dim">or refuse</text>
|
||||
|
||||
<text x="60" y="688" class="txt">Each stage cryptographically verifies</text>
|
||||
<text x="60" y="718" class="txt">the next before handing off control.</text>
|
||||
<text x="60" y="748" class="dim">Bootrom = trust anchor (can't be changed)</text>
|
||||
</svg>
|
||||
Binary file not shown.
Binary file not shown.
+275
-53
@@ -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`). |
|
||||
|
||||
#### 0x10000010–0x1000010f — 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 0x00–0x3f) plus up to 52
|
||||
external IRQ vectors (offsets 0x40–0xff = 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.
|
||||
|
||||
#### 0x10000110–0x10000127 — 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.
|
||||
|
||||
#### 0x10000128–0x1000013b — 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.
|
||||
|
||||
#### 0x10000138–0x1000014c — 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: 0x10000000–0x1000015c
|
||||
|
||||
```
|
||||
0x10000000–0x1000000f Vector Table: mandatory entries (SP, Reset, NMI, HardFault)
|
||||
0x10000010–0x1000010f Vector Table: 52 external IRQ slots → all point to default handler
|
||||
0x10000110–0x10000127 Default IRQ handler code (MRS / SUBS / BKPT)
|
||||
0x10000128–0x10000137 Binary info pointer table (start / end / callback / magic end)
|
||||
0x10000138–0x1000014b IMAGE_DEF block (d3 de ff ff ... 79 35 12 ab)
|
||||
0x10000150–0x1000015b (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! 🔍
|
||||
|
||||
@@ -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 & 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"/>
|
||||
|
||||
@@ -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"><- stops debugger</text>
|
||||
</svg>
|
||||
@@ -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>
|
||||
|
||||
@@ -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"><- infinite halt</text>
|
||||
|
||||
<text x="640" y="760" class="dim">Should never be reached!</text>
|
||||
</svg>
|
||||
@@ -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>
|
||||
|
||||
@@ -38,10 +38,38 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +95,35 @@ SECTIONS
|
||||
KEEP(*(.embedded_block))
|
||||
} > FLASH :text
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Uninitialized data (BSS) in RAM.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -38,10 +38,38 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +95,35 @@ SECTIONS
|
||||
KEEP(*(.embedded_block))
|
||||
} > FLASH :text
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Uninitialized data (BSS) in RAM.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -38,10 +38,38 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +95,35 @@ SECTIONS
|
||||
KEEP(*(.embedded_block))
|
||||
} > FLASH :text
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Uninitialized data (BSS) in RAM.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,34 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void _late_init(void)
|
||||
{
|
||||
pwm_release_reset();
|
||||
@@ -48,7 +76,7 @@ void _late_init(void)
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +95,35 @@ SECTIONS
|
||||
KEEP(*(.embedded_block))
|
||||
} > FLASH :text
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Uninitialized data (BSS) in RAM.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,34 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void _late_init(void)
|
||||
{
|
||||
servo_release_reset();
|
||||
@@ -48,7 +76,7 @@ void _late_init(void)
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +95,35 @@ SECTIONS
|
||||
KEEP(*(.embedded_block))
|
||||
} > FLASH :text
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Uninitialized data (BSS) in RAM.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -39,10 +39,38 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +95,35 @@ SECTIONS
|
||||
KEEP(*(.embedded_block))
|
||||
} > FLASH :text
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Uninitialized data (BSS) in RAM.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -38,10 +38,38 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +95,35 @@ SECTIONS
|
||||
KEEP(*(.embedded_block))
|
||||
} > FLASH :text
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Uninitialized data (BSS) in RAM.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -38,10 +38,38 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +95,35 @@ SECTIONS
|
||||
KEEP(*(.embedded_block))
|
||||
} > FLASH :text
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Uninitialized data (BSS) in RAM.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -38,10 +38,38 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +95,35 @@ SECTIONS
|
||||
KEEP(*(.embedded_block))
|
||||
} > FLASH :text
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Uninitialized data (BSS) in RAM.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -38,10 +38,38 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +95,35 @@ SECTIONS
|
||||
KEEP(*(.embedded_block))
|
||||
} > FLASH :text
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Uninitialized data (BSS) in RAM.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -39,10 +39,38 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,6 +95,35 @@ SECTIONS
|
||||
KEEP(*(.embedded_block))
|
||||
} > FLASH :text
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Uninitialized data (BSS) in RAM.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -38,10 +38,38 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,11 +101,29 @@ SECTIONS
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,34 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void _late_init(void)
|
||||
{
|
||||
timer_release_reset();
|
||||
@@ -48,7 +76,7 @@ void _late_init(void)
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,11 +101,29 @@ SECTIONS
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -39,10 +39,38 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
extern uint32_t __data_lma;
|
||||
extern uint32_t __data_start;
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
while (dst < &__data_end)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl stack_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -50,6 +50,7 @@ MEMORY
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD FLAGS(6);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,11 +101,29 @@ SECTIONS
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
|
||||
* Startup copies from __data_lma to __data_start..__data_end.
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__data_start = .;
|
||||
*(.ram_func*)
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
__data_end = .;
|
||||
} > RAM AT> FLASH :data
|
||||
|
||||
__data_lma = LOADADDR(.data);
|
||||
|
||||
/**
|
||||
* Non-secure stack symbols.
|
||||
*/
|
||||
|
||||
@@ -38,26 +38,13 @@
|
||||
|
||||
extern int main(void);
|
||||
|
||||
/**
|
||||
* @brief Linker-defined symbol: flash LMA of .data section.
|
||||
*/
|
||||
extern uint32_t __data_lma;
|
||||
|
||||
/**
|
||||
* @brief Linker-defined symbol: RAM VMA start of .data section.
|
||||
*/
|
||||
extern uint32_t __data_start;
|
||||
|
||||
/**
|
||||
* @brief Linker-defined symbol: RAM VMA end of .data section.
|
||||
*/
|
||||
extern uint32_t __data_end;
|
||||
extern uint32_t __bss_start;
|
||||
extern uint32_t __bss_end;
|
||||
|
||||
/**
|
||||
* @brief Copy initialized data and RAM-resident code from flash to RAM.
|
||||
* @retval None
|
||||
*/
|
||||
static void data_copy_init(void)
|
||||
static void _data_copy_init(void)
|
||||
{
|
||||
uint32_t *src = &__data_lma;
|
||||
uint32_t *dst = &__data_start;
|
||||
@@ -65,16 +52,24 @@ static void data_copy_init(void)
|
||||
*dst++ = *src++;
|
||||
}
|
||||
|
||||
void ram_init(void)
|
||||
static void _bss_zero_init(void)
|
||||
{
|
||||
uint32_t *dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
*dst++ = 0U;
|
||||
}
|
||||
|
||||
void _ram_init(void)
|
||||
{
|
||||
stack_init();
|
||||
data_copy_init();
|
||||
_data_copy_init();
|
||||
_bss_zero_init();
|
||||
}
|
||||
|
||||
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"bl ram_init\n\t"
|
||||
"bl _ram_init\n\t"
|
||||
"bl xosc_init\n\t"
|
||||
"bl xosc_enable_peri_clk\n\t"
|
||||
"bl reset_init_subsystem\n\t"
|
||||
|
||||
Binary file not shown.
@@ -117,9 +117,11 @@ SECTIONS
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user