1.5 KiB
1.5 KiB
Phase 8.2 - First GCC Program
Context
The first compiled program proves your hardware can execute compiler-generated code, not just carefully hand-authored assembly.
Goals
- Compile a tiny C firmware for
rv32im. - Convert the ELF into a memory image.
- Print through UART MMIO from C.
New Concepts
-march: compiler ISA target string.-mabi: ABI selection, hereilp32for 32-bit integer/long/pointer.- objcopy: tool that converts ELF into raw binary or other formats.
- Disassembly: readable assembly representation of generated machine code.
How To Think About It
Treat the compiler as an external producer of instructions. Your job is to verify that every emitted instruction is implemented or fails loudly.
Learning Tasks
- Compare C source to generated assembly.
- Identify every load/store used for UART access.
- Confirm no CSR or
fence.iinstructions appear before Phase 12.
Pitfalls
- Using the wrong
-marchand accidentally generating unsupported instructions. - Forgetting
volatileon MMIO accesses in firmware. - Assuming the compiler will preserve simple-looking loops exactly.
Tooling And Testing
- Always inspect early firmware with objdump.
- Build at low optimization first, then compare optimized output later.
- Keep firmware small enough to single-step mentally.
References
- GCC RISC-V options: https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Options.html
- RISC-V ELF psABI: https://github.com/riscv-non-isa/riscv-elf-psabi-doc
- GNU objcopy: https://sourceware.org/binutils/docs/binutils/objcopy.html