#include "InitRD.h" #include "Log.h" #include "arch/MMU.h" #include "boot/bootboot.h" #include "fs/VFS.h" #include "memory/MemoryManager.h" #include "thread/Thread.h" #include #include TarStream g_initrd; extern const BOOTBOOT bootboot; void InitRD::initialize() { u64 virtual_initrd_address = MMU::translate_physical_address(bootboot.initrd_ptr); g_initrd.initialize((void*)virtual_initrd_address, bootboot.initrd_size); } static Result vfs_create_dir_if_not_exists(const char* path, mode_t mode, uid_t uid, gid_t gid) { auto rc = VFS::create_directory(path, Credentials {}); if (rc.has_error()) { if (rc.error() == EEXIST) return {}; return rc.release_error(); } auto dir = rc.value(); dir->chmod(mode & (mode_t)~S_IFMT); dir->chown(uid, gid); return {}; } Result InitRD::populate_vfs() { TarStream::Entry entry; while (TRY(g_initrd.read_next_entry(entry))) { if (entry.type == TarStream::EntryType::RegularFile) { auto file = TRY(VFS::create_file(entry.name.chars(), Credentials {})); file->write(entry.data(), 0, entry.size); file->chmod(entry.mode & (mode_t)~S_IFMT); file->chown(entry.uid, entry.gid); } else if (entry.type == TarStream::EntryType::Directory) { TRY(vfs_create_dir_if_not_exists(entry.name.chars(), entry.mode, entry.uid, entry.gid)); } } // Now we don't need the original initrd anymore MemoryManager::free_frames(bootboot.initrd_ptr, get_blocks_from_size(bootboot.initrd_size, ARCH_PAGE_SIZE)); return {}; }