Overview
Build infrastructure to create an init ramdisk (initrd) that is embedded directly in the kernel binary at build time. The ramdisk is unpacked into tmpfs at kernel boot, making files (e.g. shared libraries like libc.so, ld-musl-riscv64.so.1) available at well-known paths without requiring any bulk storage device.
Motivation
Dynamic linking (#199) requires shared libraries (e.g. /lib/ld-musl-riscv64.so.1, /lib/libc.so) to be accessible at runtime. Currently, userspace binaries are embedded directly in the kernel binary. For shared libraries this approach doesn't scale — we need a way to provide files at well-known paths at runtime.
Embedding an initrd in the kernel binary avoids introducing any dependency on a block device or virtio-fs device. The kernel carries all required files within itself and unpacks them into tmpfs at boot, keeping the setup simple and self-contained.
Approach
Pack files (shared libraries, etc.) into a CPIO archive at build time and embed the archive directly in the kernel binary (e.g. as a linker section or a static byte array). At kernel boot, walk the CPIO archive and extract each entry into tmpfs under a standard path (e.g. /lib).
This approach:
- Requires no block device or virtual filesystem device attached to QEMU
- Reuses the existing tmpfs and VFS infrastructure
- Integrates naturally into the existing
just build workflow
- Is the simplest path to unblocking dynamic linking
Implementation Steps
- Build tooling: Add a build step (e.g. in
justfile or a build script) that collects shared libraries from the musl sysroot and packs them into a CPIO archive.
- Embed archive in kernel: Include the CPIO archive as a static byte array in the kernel binary (e.g. via
include_bytes! or a linker section).
- Boot-time extraction: At kernel init, parse the embedded CPIO archive and populate tmpfs with its contents (files, symlinks, directories) under
/lib or similar.
- Integration: Ensure the linker/dynamic loader can find
ld-musl-riscv64.so.1 at the expected path.
Relevant Files
kernel/src/fs/ — VFS layer (tmpfs, where files will be extracted)
kernel/src/lib.rs — Kernel init (where extraction should be triggered)
justfile — Build workflow
userspace/ — Musl libc sysroot (source of shared libraries)
Created by Claude Code
Overview
Build infrastructure to create an init ramdisk (initrd) that is embedded directly in the kernel binary at build time. The ramdisk is unpacked into tmpfs at kernel boot, making files (e.g. shared libraries like
libc.so,ld-musl-riscv64.so.1) available at well-known paths without requiring any bulk storage device.Motivation
Dynamic linking (#199) requires shared libraries (e.g.
/lib/ld-musl-riscv64.so.1,/lib/libc.so) to be accessible at runtime. Currently, userspace binaries are embedded directly in the kernel binary. For shared libraries this approach doesn't scale — we need a way to provide files at well-known paths at runtime.Embedding an initrd in the kernel binary avoids introducing any dependency on a block device or virtio-fs device. The kernel carries all required files within itself and unpacks them into tmpfs at boot, keeping the setup simple and self-contained.
Approach
Pack files (shared libraries, etc.) into a CPIO archive at build time and embed the archive directly in the kernel binary (e.g. as a linker section or a static byte array). At kernel boot, walk the CPIO archive and extract each entry into tmpfs under a standard path (e.g.
/lib).This approach:
just buildworkflowImplementation Steps
justfileor a build script) that collects shared libraries from the musl sysroot and packs them into a CPIO archive.include_bytes!or a linker section)./libor similar.ld-musl-riscv64.so.1at the expected path.Relevant Files
kernel/src/fs/— VFS layer (tmpfs, where files will be extracted)kernel/src/lib.rs— Kernel init (where extraction should be triggered)justfile— Build workflowuserspace/— Musl libc sysroot (source of shared libraries)Created by Claude Code