Your bootloader accepts Intel HEX data over UART and writes it directly into IMEM. There is no authentication, no encryption, and no integrity check.
Anyone with physical access to the serial port can:
.hex file that overwrites the entire program.This is exactly how IoT devices get compromised: a UART console left exposed on a production PCB (often labeled TX/RX on the board) gives an attacker full control. In 2020, researchers compromised a popular home router by soldering wires to its UART pads and loading a modified firmware.
A secure boot chain prevents unauthorized code from running:
| Component | Your Project 2 | Production system |
|---|---|---|
| Boot code location | Writable SRAM | Immutable ROM |
| Code authentication | None | ECDSA / RSA signature |
| Integrity check | ihex checksum (per-line) | SHA-256 over entire image |
| Encryption in transit | None (plaintext UART) | AES-encrypted payload |
| Anti-rollback | None | Monotonic version counter in OTP fuse |
0x0100.imem_locked = 1, no further writes to IMEM are accepted until the next reset.Every peripheral in your memory map is accessible from any code:
In production SoCs, a bus firewall (or TrustZone on Arm) restricts which masters can access which address ranges. RISC-V's PMP can enforce this at the CPU level:
0x0002_xxxx.Project 2 security question: "Your bootloader has no authentication. Describe a practical attack that exploits this and one mechanism that would prevent it."
Every peripheral you added in Project 2 consumes power — even when idle:
| Peripheral | Idle behavior | Power impact |
|---|---|---|
| UART TX | Shift register holds 1 (mark) |
Minimal — no toggles |
| UART RX | Oversampling counter runs continuously | Clock toggles 16× per bit period, even when no data arrives |
| Timer | 64-bit counter increments every cycle | 64 flip-flops toggle every clock edge |
| GPIO | Output latches hold last value | Minimal |
The bus routes every load/store through the address decoder, even when the target is DMEM (the most common case). Every bus transaction toggles the mux/decoder logic for all peripherals, not just the target.
In production SoCs:
You can measure your design's power with a USB power meter:
A faster baud rate sends the same data in less time — but does it save energy?
For the bootloader, higher baud rate is strictly better: same data, less waiting, less energy.
Your memory map (M03A01) is a hardware/software contract:
0x0000_0000 – 0x0000_0FFF IMEM (4 KB)
0x0001_0000 – 0x0001_0FFF DMEM (4 KB)
0x0002_0000 UART
0x0002_0100 Timer
0x0002_0200 GPIO
0x0002_0300 Accelerator (reserved)
#define or a header file for all addresses — never hardcode 0x00020000 in driver code.A mismatch between the memory map in hardware and in software is one of the hardest bugs to find — everything synthesizes, everything compiles, but loads/stores go to the wrong peripheral.
Module 4 — TinyML on the Edge: the KWS model in depth, the inference kernel in C, and profiling — finding exactly which operation is responsible for the baseline cycle count we just measured.