Build system changes: - scripts/gen_initrd.sh packs all files from apps/ into a newc-format CPIO archive at build/isodir/boot/initrd.cpio. - CMakeLists.txt adds 'initrd' target as ISO dependency. GRUB loads the archive as a Multiboot2 module via 'module2 /boot/initrd.cpio'. - apps/README added as placeholder file for initial ramdisk content. Kernel changes: - kernel.c scans Multiboot2 tags for MULTIBOOT_TAG_TYPE_MODULE to find the initrd's physical address range, then passes it to cpio_init(). - cpio.c/h implements a parser for the SVR4/newc CPIO format: - cpio_init(): lists archive contents on startup - cpio_find(): look up a file by name (handles ./ prefix) - cpio_next(): iterate through all entries - cpio_count(): count files in archive - The initrd lives in identity-mapped physical memory, so no additional mapping is needed to access it. Verified in QEMU: GRUB loads the module at 0x0014A000, CPIO parser finds the README file (38 bytes). All existing functionality (Ring 3 processes, syscalls) continues to work.
2.0 KiB
CPIO Initial Ramdisk
Overview
The initial ramdisk (initrd) provides files to the kernel at boot time before any filesystem drivers are available. It is a CPIO archive in SVR4/newc format, loaded by GRUB as a Multiboot2 module.
Build Process
During the build, the script scripts/gen_initrd.sh packs all files from the
apps/ directory into a CPIO archive:
apps/
├── README (placeholder)
├── hello-world (future: flat binary)
└── sh (future: shell binary)
The archive is placed at build/isodir/boot/initrd.cpio and included in the
ISO image. GRUB loads it as a module via:
module2 /boot/initrd.cpio
CPIO Format
The newc (SVR4) CPIO format uses 110-byte headers with hex ASCII fields:
Offset Size Field
0 6 Magic ("070701")
6 8 Inode
14 8 Mode
22 8 UID
30 8 GID
38 8 Nlink
46 8 Mtime
54 8 Filesize
62 8 Devmajor
70 8 Devminor
78 8 Rdevmajor
86 8 Rdevminor
94 8 Namesize
102 8 Check
After the header: filename (namesize bytes, padded to 4-byte boundary),
then file data (filesize bytes, padded to 4-byte boundary). The archive
ends with a TRAILER!!! entry.
Kernel Interface
The kernel finds the initrd by scanning Multiboot2 boot information for
MULTIBOOT_TAG_TYPE_MODULE (type 3). The module's physical memory range
is identity-mapped, so it can be read directly.
#include "cpio.h"
// Find a file
cpio_entry_t entry;
if (cpio_find("hello-world", &entry) == 0) {
// entry.data = pointer to file contents
// entry.datasize = file size
}
// Iterate all files
uint32_t offset = 0;
while (cpio_next(&offset, &entry) == 0) {
// entry.name, entry.data, entry.datasize
}
Files
scripts/gen_initrd.sh— Build script to generate CPIO archivesrc/cpio.h/src/cpio.c— CPIO parser (find, iterate, count)CMakeLists.txt—initrdtarget andmodule2in grub.cfg