Discussion-02
Bare-Metal Graphics on RISC-V
ECE391 — Systems Programming
Quick Start
make -C release run-gold
make -C release run-demo
make -C release debug-demo
starry-night screensaver
A starry-night screensaver that animates stars, windows, and a blinking beacon
Discussion Goal: we will talk about each of the component in the entire deployment pipeline.
Your task: Writing callback functions that helps the rendering pipeline.
How the Makefile Works
Key Concepts
�
Cross-compilation
riscv64-unknown-elf-*
�
Linker script
kernel.ld sets layout
Entry at 0x80000000
�
Target outputs
demo-kernel.elf
gold-kernel.elf
What is a Makefile?
A dependency graph runner: targets depend on files; it rebuilds only what is out of date.
Basic Structure
�
target: dependencies
command to build target
�
Example:
mp1.o: mp1.s
$(AS) $(ASFLAGS) -o $@ $<
�
Translation:
$@ = target (mp1.o)
$< = first dependency (mp1.s)
$^ = all dependencies
Why Make Matters
�
1. Incremental builds
Only recompile changed files
�
2. Dependency tracking
Knows which files affect which
�
3. Reproducibility
Same commands every time
�
4. Abstraction
Complex builds → simple commands
Makefile: Variables & Tools
Tool Variables
�
PREFIX=riscv64-unknown-elf-
CC=$(PREFIX)gcc
AS=$(PREFIX)as
LD=$(PREFIX)ld
�
Cross-compilation tools for RISC-V
Key CFLAGS Explained
�
-mcmodel=medany
Memory model for RISC-V
-nostdlib
No standard library (bare metal!)
-ffreestanding
No OS assumptions
Object Files List OBJS = mp1.o start.o
These object files are linked together to form the kernel. Your mp1.s becomes mp1.o after assembly.
Makefile: Important Targets
demo-kernel.elf
�
demo-kernel.elf: $(OBJS) demo.o kernel.a
$(LD) -T kernel.ld -o $@ $^
�
Links your mp1.o + demo.o + kernel
gold-kernel.elf
�
gold-kernel.elf: $(OBJS) gold.o kernel.a
$(LD) -T kernel.ld -o $@ $^
�
Reference implementation
run-demo
�
run-demo: demo-kernel.elf
$(QEMU) $(QEMUOPTS) -kernel $<
�
Builds then launches QEMU
debug-demo
�
debug-demo: demo-kernel.elf
$(QEMU) ... -kernel $< -S -s
�
-S -s: wait for GDB on :1234
Makefile: Pattern Rules & Tests
Pattern Rules (% is a wildcard)
�
test_%.elf: $(OBJS) tests/test_%.o kernel.a
$(LD) $(LDFLAGS) -T kernel.ld -o $@ $^
�
This single rule handles ALL test files! When you run:
make test_add_star_simple.elf
Make substitutes % = add_star_simple
Test Workflow Examples
make test_add_star_simple.elf → compile test
make run-test_add_star_simple → run test
make debug-test_add_star_simple → debug test
Plotting Pixels
The framebuffer model: a 2D array of pixels in RAM
Why gpu_draw() Exists
The Demo Application
The screensaver behavior: timer -> update model -> render -> flush
The Render Pipeline
demo_render_scene() calls your callback functions in sequence
How your code is graded
weak symbols let your code override placeholders at link time
Data Structures
Window Array
skyline_windows[0..cnt)
Contiguous array — swap last on remove
Beacon Struct
skyline_beacon
Blink timing: (tick % period) < ontime
Bare Metal Boot Flow
No OS means: no processes, no syscalls, no virtual memory, no file system
Setup Example
Your Setup
Dev Machine
(Your Laptop)
�
• Cross compiler
• QEMU emulator
• GDB debugger
�
Produces .elf for
RISC-V target
QEMU
(Emulator)
�
• RISC-V virt board
• virtio-gpu device
• Serial console
• Timer/interrupts
�
Runs bare-metal ELF
Autograder
(Test Machine)
�
• Same QEMU env
• Test kernels
• ABI compliance
�
Tests linked as main
Student Implementation
Your File
mp1.s
�
RISC-V assembly implementation
Required Functions
�
Star operations
add_star, remove_star, draw_star
�
Window operations
add_window, remove_window, draw_window
�
Beacon
draw_beacon (start_beacon given)
Key Requirements
�
1. Correct data structure manipulation
Linked list for stars, array for windows
�
2. Proper clipping
Don't draw outside 640×480 screen
�
3. Time-based beacon blinking
(tick % period) < ontime -> lit
�
4. RISC-V calling convention
Save/restore s0-s11, ra properly
Debugging Playbook
Build Issues
• Wrong target (demo vs gold)
• Missing toolchain
• Linker errors
Data Structure Bugs
• List corruption (next ptr)
• Wrong head update
• Array not compacted
Drawing Bugs
• Index math: x + y*640
• No clipping at edges
• Wrong pixel format
ABI / Calling Convention
• Clobbered s* registers
• Stack misalignment
GDB Quick Start: make debug-demo -> riscv64-unknown-elf-gdb demo-kernel.elf -> target remote :1234