1.8 KiB
1.8 KiB
Phase 10 - Minimal ELF Loader
Context
This phase lets the BIOS receive GCC-built programs as ELF files and run them without rebuilding the FPGA bitstream.
Goals
- Parse enough ELF32 to recognize RISC-V executable files.
- Load
PT_LOADsegments into memory and zero BSS. - Jump to
e_entrywith a fixed tiny-program ABI.
New Concepts
- ELF header: file-level metadata describing architecture, entry point, and tables.
- Program header: runtime load description used by loaders.
PT_LOAD: segment that must be copied into memory before execution.- BSS: zero-initialized memory represented by
memsz > filesz.
How To Think About It
Do not build a general-purpose dynamic loader. Build a strict loader for the exact firmware shape you produce: static, little-endian, non-relocatable RV32 ELF files with fixed physical addresses.
Learning Tasks
- Read the ELF header fields needed to reject unsupported files.
- Map
p_paddrorp_vaddrto your executable memory window. - Define the stack pointer and argument registers at program entry.
- Decide how a loaded program returns a status code to the BIOS.
Pitfalls
- Trusting malformed ELF offsets or sizes.
- Forgetting to zero the BSS tail of a loadable segment.
- Accidentally accepting relocatable or dynamically linked binaries.
- Loading a segment over the BIOS itself.
Tooling And Testing
- Use
readelf -h -landobjdump -don every early payload. - Start with one fixed link address and one loadable segment.
- Add loud rejection messages for unsupported ELF class, endianness, machine, or type.
References
- ELF specification overview: https://refspecs.linuxfoundation.org/elf/elf.pdf
- RISC-V ELF psABI: https://github.com/riscv-non-isa/riscv-elf-psabi-doc
- GNU binutils
readelfdocumentation: https://sourceware.org/binutils/docs/binutils/readelf.html