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.
82 lines
2.0 KiB
Markdown
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
|