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.
This commit is contained in:
81
docs/cpio.md
Normal file
81
docs/cpio.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user