CS 452/652 Winter 2026 - Lecture 2
Memory and Devices
Jan 8, 2026 prev next
BCM - Broadcom BCM2711 data sheet
Memory
- see BCM Section 1.2.1, Figure 1: "Low Peripheral" mode
- main memory: assume 0x00000000 - 0x3FFFFFFF (1 GB)
- top 76MB used for VC (config.txt)
- memory-mapped device registers: "magic" addresses
- see BCM Section 1.2.4: base address 0x7E000000 → 0xFE000000
Loading
- typical (simple) ELF loading
- linker creates ELF file: text, rodata, data, bss, etc. sections
- loader sets up memory: code, data, heap, stack
- exection jumps to well-defined entry point
- load and execute kernel8.img file
- image file is produced from ELF - includes code and data (not bss)
- execution jumps to 0x80000 (text set up in linker script)
- at kernel entry, program has code, data, stack (no heap)
- MMU setup
| start |
end |
description |
| 0x00000000 |
0x001FFFFF |
code (R/O for EL0) |
| 0x00200000 |
0x3FFFFFFF |
data (R/W) |
| 0x40000000 |
0xFFFFFFFF |
device (no caching) |
- RPi warm start: memory might not be reset
- bss section needs to be initialized to 0 → linker script & code
Programming
- C/C++ provide very good control over memory layout of structured data
- use pointer casting to switch between unstructured and structured view (or union declaration)
- if necessary, GCC extensions can be used to increase control over memory layout (packed, aligned, etc.)
- C++ constructors need to be run &rarr manually; linker script & code
Timer
- no time of day needed, no remote synchronization (very hard problem)
- ARM timer (BCM Chap 12) vs. System timer (BCM Chap 10)
- ARM timer follows CPU-frequency → use system timer
- system timer
- free-running counter at stable frequency: 1 MHz
- 7 control registers starting at offset 0x3000
- CLo/CHi: timer counter
- C0-3: compare and set status in CS
- query timer and/or wait for interrupt via compare registers
General-Purpose Input/Output (GPIO)
- configurable hardware interface
- BCM Chap 5, Page 78, registers at offset 0x00200000
- iotest contains code for setting up GPIO
- no reason to mess with this
Universal Asynchronous Receiver/Transmitter (UART)
- serial (character) device: 1 byte at a time
- UART: standard "state machine" at the end of serial line
- BCM Chap 11 (not Chap 2): UART0
- device registers at offset 0x201000
- data register (DR) at offset 0x00
- FIFO buffer (optional, default size 1)
- configuration: speed, byte representation, FIFO
- terminal: 115200 baud (8 bits, no parity, 1 stop bit)
- output (transmit, TX)
- write to DR
- UART moves to FIFO
- FIFO entries sent via serial line
- input (receive, RX)
- reception from serial line into FIFO
- first element in FIFO is always available in DR
- read from DR
- flag register (FR) describes status of TX/RX buffers (full/empty)
- check before send/receive
- timing
- actual communication happens in parallel to UART processing
- receive: need to be fast enough
- transmit: paced according to line speed when checking TX state in FR
- how long does it take to transmit a byte to the console?
- sender speed vs. serial line speed vs. receiver speed
- optional: flow control
Serial Peripheral Interface (SPI)
- used for communication with MCP2515 / CAN bus interface
- BCM Chap 9 (not Section 2.3): SPI0
- device registers at offset 0x204000
- not just a single standard; very configurable and flexible
- synchronous bidirectional transmission of bytes, 1-3 in, same out
- "transaction" of up to N bytes
- actual sending/receiving happens in parallel to processing
- semantics determined by usage; FIFOs not used in our code
Polling Loop