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.
93 lines
2.5 KiB
C
93 lines
2.5 KiB
C
/**
|
|
* @file cpio.h
|
|
* @brief CPIO newc archive parser.
|
|
*
|
|
* Parses CPIO archives in the SVR4/newc format (magic "070701").
|
|
* Used to read files from the initial ramdisk loaded by GRUB.
|
|
*/
|
|
|
|
#ifndef CPIO_H
|
|
#define CPIO_H
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
|
|
/**
|
|
* CPIO newc header (110 bytes).
|
|
* All fields are 8-character hexadecimal ASCII strings.
|
|
*/
|
|
typedef struct cpio_newc_header {
|
|
char magic[6]; /**< Must be "070701". */
|
|
char ino[8];
|
|
char mode[8];
|
|
char uid[8];
|
|
char gid[8];
|
|
char nlink[8];
|
|
char mtime[8];
|
|
char filesize[8];
|
|
char devmajor[8];
|
|
char devminor[8];
|
|
char rdevmajor[8];
|
|
char rdevminor[8];
|
|
char namesize[8];
|
|
char check[8];
|
|
} cpio_newc_header_t;
|
|
|
|
/** Size of the CPIO newc header in bytes. */
|
|
#define CPIO_HEADER_SIZE 110
|
|
|
|
/** CPIO newc magic string. */
|
|
#define CPIO_MAGIC "070701"
|
|
|
|
/** Trailer entry name that marks end of archive. */
|
|
#define CPIO_TRAILER "TRAILER!!!"
|
|
|
|
/**
|
|
* CPIO file entry (result of iteration or lookup).
|
|
*/
|
|
typedef struct cpio_entry {
|
|
const char *name; /**< Filename (pointer into archive). */
|
|
uint32_t namesize; /**< Length of filename including NUL. */
|
|
const void *data; /**< Pointer to file data within archive. */
|
|
uint32_t datasize; /**< Size of file data in bytes. */
|
|
uint32_t mode; /**< File mode/permissions. */
|
|
} cpio_entry_t;
|
|
|
|
/**
|
|
* Initialize the CPIO parser with the archive location.
|
|
*
|
|
* @param archive_start Pointer to the start of the CPIO archive in memory.
|
|
* @param archive_size Size of the archive in bytes (0 if unknown).
|
|
*/
|
|
void cpio_init(const void *archive_start, uint32_t archive_size);
|
|
|
|
/**
|
|
* Find a file in the CPIO archive by name.
|
|
*
|
|
* @param name Filename to search for (without leading "./").
|
|
* @param entry Output: filled with file information if found.
|
|
* @return 0 on success, -1 if not found.
|
|
*/
|
|
int cpio_find(const char *name, cpio_entry_t *entry);
|
|
|
|
/**
|
|
* Iterate through all entries in the CPIO archive.
|
|
*
|
|
* Call with *offset = 0 to start. Returns 0 on success, -1 when no
|
|
* more entries exist or the TRAILER is reached.
|
|
*
|
|
* @param offset In/out: current position in the archive.
|
|
* @param entry Output: filled with the next entry's information.
|
|
* @return 0 on success, -1 at end of archive.
|
|
*/
|
|
int cpio_next(uint32_t *offset, cpio_entry_t *entry);
|
|
|
|
/**
|
|
* Get the number of files in the CPIO archive (excluding TRAILER).
|
|
*
|
|
* @return Number of files.
|
|
*/
|
|
uint32_t cpio_count(void);
|
|
|
|
#endif /* CPIO_H */
|