How mazunix/mazu works
1. Overall shape
- Mazu is a bare-metal RISC-V 64-bit RTOS kernel with a small user/task layer built into the same image.
- The repository is organized around one kernel, one architecture port (arch/riscv64), a set of in-kernel subsystems (kernel/), a small user-space program set (user/), and a packed runtime root filesystem (rootfs/).
2. Boot and hardware bring-up
- Execution starts in arch/riscv64/entry.c, with OpenSBI handing off control and passing the FDT.
- Early boot discovers QEMU virt hardware via FDT, initializes the UART, PLIC, paging, and per-CPU state, then enters the kernel init path.
- This is the main boundary between firmware/SoC initialization and the portable kernel core.
3. Configuration and build-time shaping
- Build-time behavior is driven by Kconfig (configs/Kconfig) plus defconfigs/fragments.
- The build system generates config headers and conditionally compiles major features like SMP, TCP, UDP, WebSocket, semihosting, virtio-blk, and writable ramfs.
- This means architecture diagrams should show features as compile-time gates, not runtime plugins.
4. Kernel initialization and dependency graph
- kernel/init/main.c and kernel/init/initgraph.c run subsystem startup in dependency order.
- The init sequence brings up memory, paging, allocators, scheduler services, networking, and optional protocol/service tasks.
- The dependency graph is important: services are not launched ad hoc; they are started after their supporting infrastructure is ready.
5. Scheduling and CPU topology
- The scheduler is a core subsystem under kernel/sched/, designed for hard real-time and SMP from the start.
- Each hart has per-CPU run queues, callout state, and timing data; gp is used for per-CPU access on RISC-V.
- Timer interrupts and traps drive preemption, wakeups, load balancing, and deadline maintenance; long-lived kernel service work runs as ordinary scheduled tasks.
6. Memory management and object allocation
- Physical page allocation lives in kernel/mm/buddy.c, while general kernel virtual allocation is handled by kernel/mm/kvalloc.c.
- Higher-level subsystems rely heavily on pool and arena allocators from include/mazu/ for fixed-size objects and request-scoped temporary data.
- Page tables are set up in arch/riscv64/paging.c using Sv39 with identity-mapped kernel memory and shared user mappings, so the architecture is “single address space with controlled user regions,” not full process isolation.
7. Process, syscall, and user-pointer boundary
- Process creation, ELF loading, spawning, signals, pipes, and syscalls are in kernel/proc/.
- Syscall handling is guarded by per-process allow-lists and user-pointer validation, with uaccess enforcing boundary checks before data crosses kernel/user space.
- The process boundary is therefore security-sensitive but intentionally lightweight: no separate VM per task, just VMA-style containment and policy checks.
8. Synchronization and blocking primitives
- The kernel provides Linux-like synchronization primitives in kernel/sync/: mutexes, rwlocks, semaphores, barriers, condvars, futexes, and synchronization handles.
- Wait queues and timer callouts connect these primitives to scheduler sleep/wakeup behavior.
- Lock ordering is a first-class concern, and many kernel subsystems assume the shared lock hierarchy enforced by lockdep-style checks.
9. Filesystem stack and namespace model
- Filesystems are split between synthetic namespaces and data-backed storage under kernel/fs/.
- vfs.c dispatches path lookups across mounted filesystems; devfs, procfs, and netfs expose kernel state as files, while ramfs and sfs store actual content.
- bcache only exists for the disk-backed path; synthetic filesystems are generated on demand and not page-cached.
- This is a major architectural boundary: system control and observability are file-based rather than ioctl/socket-based.
10. Networking pipeline
- Networking starts at the QEMU virtio-mmio device driver (drivers/net/virtio_mmio.c) and flows into kernel/net/netdev.c.
- Packets are processed through ARP, IPv4, ICMP, UDP, DNS/DHCP/mDNS, and TCP, with send-buffer and retransmission logic managed in-kernel.
- The TCP implementation is connection-oriented but not socket-based; callers use direct kernel APIs such as tcp_conn_listen, tcp_conn_accept, tcp_conn_connect, tcp_conn_send, and tcp_conn_recv.
- This makes the network stack a direct service layer inside the kernel, not a user-space networking subsystem.
11. Web service and user-facing runtime
- The main application workload is the kernel-integrated web server in user/net/web.c.
- It serves static assets from rootfs/web/ and exposes REST endpoints for stats, TCP/ARP tables, klog, filesystem browsing, shell I/O, and SSE/WebSocket streaming.
- The “shell” and telemetry interfaces are ordinary tasks using the TCP stack, so the web UI is not a separate external appliance; it is part of the kernel workload model.
12. Root filesystem and packaged runtime content
- rootfs/ is archived into the kernel image at build time.
- It contains boot-time configuration, example content, and the web UI assets used by the HTTP server.
- This means the runtime content model is static-at-build, mutable-at-boot only where the in-kernel filesystems allow it.
13. Testing, verification, and CI
- The repository has both kernel tests (tests/) and host-side tests under tests/host/.
- CI scripts cover formatting, static analysis, security checks, QEMU runs, TAP networking, and semihosted self-tests.
- Tooling is centered on cross-compilation for RISC-V, QEMU virt, and Linux-hosted automation; architecture diagrams should include these as the primary dev/test environment.
14. External dependencies and execution environment
- The system assumes OpenSBI firmware, QEMU virt, virtio devices, PLIC, and either SLIRP or TAP networking during development.
- Host-side scripts also support network setup and TLS relay/proxying for development-time access to the plaintext HTTP service.
- These are important infrastructure boundaries because they shape boot, I/O, and how the kernel’s networking is exercised in practice.
Main entry points: initgraph.c Init graph · tcp.c Protocols · entry.c Boot entry · proc.c Proc/syscall
Components 28
Boot & Arch
RISC-V bring-up, traps, paging, and hardware handoff
- Boot entry · OpenSBI handoff, early CPU/FDT bring-up, and kernel entry
arch/riscv64/entry.c - FDT parse · Device tree discovery and platform description
arch/riscv64/fdt.c - Paging · Kernel/user mapping setup and address space control
arch/riscv64/paging.c - Traps · Interrupt and exception entry for preemption and syscall boundaries
arch/riscv64/trap.c - SBI/semihost · Firmware calls and semihosting support
arch/riscv64/sbi.c
Kernel Core
Initialization, scheduling, memory, sync, timers, and proc control
- Kernel init · Top-level subsystem startup sequence
kernel/init/main.c - Init graph · Ordered dependency-based service startup
kernel/init/initgraph.c - Scheduler · Per-CPU run queues, deadlines, wakeups, and preemption
kernel/sched/core.c - Wait queues · Sleep and wake coordination for blocking paths
kernel/sched/waitqueue.c - Memory mgr · Physical pages and kernel virtual allocations
kernel/mm/buddy.c - Proc/syscall · ELF loading, spawn, signals, pipes, syscalls, and user-pointer checks
kernel/proc/proc.c - Uaccess · Validation boundary for copying data across kernel/user space
kernel/proc/uaccess.c - Sync primitives · Mutexes, rwlocks, semaphores, barriers, condvars, futexes, and handles
kernel/sync/mutex.c - Timers · Callouts and POSIX timers feeding scheduling and blocking
kernel/timer/callout.c
FS & Storage
Virtual filesystems and storage-backed content
- VFS · Mount and pathname dispatch across filesystems
kernel/fs/vfs.c - Synthetic FS · Generated namespaces for device, proc, and network state
kernel/fs/devfs.c - Backed FS · RAM and disk-backed filesystem implementations
kernel/fs/ramfs.c - Block cache · Cache layer used by storage-backed filesystems
kernel/fs/bcache.c
Networking
Device ingress through protocol stack and kernel TCP/UDP services
- Netdev · Kernel network device front-end
kernel/net/netdev.c - Virtio MMIO · QEMU virtio network device driver
drivers/net/virtio_mmio.c - Protocols · ARP, IPv4, ICMP, UDP, DNS/DHCP/mDNS, and TCP processing
kernel/net/tcp.c - Send buffers · TCP buffering and retransmission support
kernel/net/send_buf.c
Runtime & User
Built-in user tasks and packaged root filesystem
- Web server · Kernel-integrated HTTP service and telemetry shell
user/net/web.c - Shell task · Built-in interactive task using TCP services
user/shell.c - RootFS · Build-time archived runtime content and web assets
rootfs/web/index.html
Build & Test
Configuration, scripts, and verification environment
- Kconfig · Compile-time feature selection and generated configuration
configs/Kconfig - Build scripts · Defconfig, image packing, and test automation scripts
scripts/make_config.sh - Tests · In-kernel and host-side verification suite
tests/tests-initgraph.c
Connections 32
- Boot entry → FDT parse: discovers · Boot code uses FDT to identify the QEMU virt platform
- Boot entry → Paging: sets up · Early architecture bring-up establishes kernel mappings
- Boot entry → Traps: installs · Trap/interrupt handling is initialized during boot
- Boot entry → SBI/semihost: calls · Firmware services and semihosting are accessed through SBI
- Boot entry → Kernel init: enters · Architecture handoff transfers control into kernel initialization
- Kernel init → Init graph: orders · Subsystem startup follows dependency graph sequencing
- Init graph → Memory mgr: starts · Memory management comes up early for all later subsystems
- Init graph → Scheduler: starts · Scheduler services are required for kernel tasks and services
- Init graph → Sync primitives: starts · Locking and blocking primitives underpin most kernel services
- Init graph → VFS: starts · Namespace services are initialized after core infrastructure
- Init graph → Netdev: starts · Networking is enabled once base kernel services exist
- Scheduler → Wait queues: uses · Blocking primitives rely on scheduler sleep and wake paths
- Timers → Scheduler: drives · Timer events trigger preemption and deadline maintenance
- Proc/syscall → Uaccess: guards · Syscalls validate pointers before copying user data
- Proc/syscall → Scheduler: spawns · Processes and kernel tasks are scheduled on the run queues
- Proc/syscall → Sync primitives: blocks on · Pipes, signals, and waits use synchronization primitives
- VFS → Synthetic FS: dispatches · Devfs, procfs, and netfs expose kernel state as files
- VFS → Backed FS: mounts · Ramfs and sfs hold actual file content
- Backed FS → Block cache: uses · Storage-backed paths pass through the block cache
- Virtio MMIO → Netdev: feeds · Device driver hands packets to the kernel networking front-end
- Netdev → Protocols: routes · Ingress and egress flow into protocol processing
- Protocols → Send buffers: buffers · TCP send/receive and retransmission use internal buffers
- Protocols → Web server: serves · Kernel TCP APIs support the built-in HTTP service
- Protocols → Shell task: supports · Interactive shell task communicates over the TCP stack
- RootFS → Web server: packages · Static web assets are archived into the kernel image
- Kconfig → Kernel init: gates · Build-time options shape which services are compiled and started
- Kconfig → Protocols: gates · TCP, UDP, DNS, DHCP, and WebSocket features are compile-time selected
- Kconfig → Backed FS: gates · Writable ramfs and storage options are controlled at build time
- Build scripts → Kconfig: drives · Defconfig and image-generation tooling produce the build configuration
- Tests → Kernel init: verifies · Kernel tests exercise init ordering and core subsystems
- Tests → Proc/syscall: verifies · Process, syscall, and uaccess behavior are covered by tests
- Tests → Protocols: verifies · Network protocol behavior is checked by kernel and host tests