Files
claude-os/docs/cpio.md
AI 3d5fb4c267 Add CPIO initial ramdisk with build infrastructure and parser (AI)
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.
2026-02-23 12:16:24 +00:00

82 lines
2.0 KiB
Markdown

# 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.
```c
#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 archive
- `src/cpio.h` / `src/cpio.c` — CPIO parser (find, iterate, count)
- `CMakeLists.txt``initrd` target and `module2` in grub.cfg