1 of 18

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

2 of 18

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.

3 of 18

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

4 of 18

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

5 of 18

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.

6 of 18

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

7 of 18

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

8 of 18

Plotting Pixels

The framebuffer model: a 2D array of pixels in RAM

9 of 18

Why gpu_draw() Exists

10 of 18

The Demo Application

The screensaver behavior: timer -> update model -> render -> flush

11 of 18

The Render Pipeline

demo_render_scene() calls your callback functions in sequence

12 of 18

How your code is graded

weak symbols let your code override placeholders at link time

13 of 18

Data Structures

Window Array

skyline_windows[0..cnt)

Contiguous array — swap last on remove

Beacon Struct

skyline_beacon

Blink timing: (tick % period) < ontime

14 of 18

Bare Metal Boot Flow

No OS means: no processes, no syscalls, no virtual memory, no file system

15 of 18

Setup Example

16 of 18

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

17 of 18

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

18 of 18

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