initrd.c
1 #include "initrd.h" 2 #include "memory.h" 3 #include "string.h" 4 #include "kernel.h" 5 6 struct initrd_header* initrd_header; 7 struct initrd_file_header* file_headers; 8 struct fs_node* initrd_root; 9 struct fs_node* initrd_dev; 10 struct fs_node* root_nodes; 11 uint32_t nroot_nodes; 12 13 static struct dirent dirent; 14 15 static uint32_t initrd_read(struct fs_node* node, uint32_t offset, uint32_t size, uint8_t* buffer) { 16 struct initrd_file_header header = file_headers[node->inode]; 17 if (offset > header.length) { 18 return 0; 19 } 20 if (offset + size > header.length) { 21 size = header.length - offset; 22 } 23 memcpy(buffer, (uint8_t*)(header.offset + offset), size); 24 return size; 25 } 26 27 static struct dirent* initrd_readdir(struct fs_node* node, uint32_t index) { 28 (void)node; 29 if (index >= nroot_nodes) { 30 return 0; 31 } 32 33 strcpy(dirent.name, root_nodes[index].name); 34 dirent.name[strlen(root_nodes[index].name)] = 0; 35 dirent.ino = root_nodes[index].inode; 36 return &dirent; 37 } 38 39 static struct fs_node* initrd_finddir(struct fs_node* node, char* name) { 40 (void)node; 41 for (uint32_t i = 0; i < nroot_nodes; i++) { 42 if (!strcmp(name, root_nodes[i].name)) { 43 return &root_nodes[i]; 44 } 45 } 46 return 0; 47 } 48 49 struct fs_node* initrd_init(uint32_t location) { 50 // Initialize the main and file header pointers 51 initrd_header = (struct initrd_header*)location; 52 file_headers = (struct initrd_file_header*)(location + sizeof(struct initrd_header)); 53 54 // Initialize the root directory 55 initrd_root = (struct fs_node*)kmalloc(sizeof(struct fs_node)); 56 strcpy(initrd_root->name, "initrd"); 57 initrd_root->mask = initrd_root->uid = initrd_root->gid = initrd_root->inode = initrd_root->length = 0; 58 initrd_root->flags = FS_DIRECTORY; 59 initrd_root->read = 0; 60 initrd_root->write = 0; 61 initrd_root->open = 0; 62 initrd_root->close = 0; 63 initrd_root->readdir = &initrd_readdir; 64 initrd_root->finddir = &initrd_finddir; 65 initrd_root->ptr = 0; 66 initrd_root->impl = 0; 67 68 // Initialize file nodes 69 nroot_nodes = initrd_header->nfiles; 70 root_nodes = (struct fs_node*)kmalloc(sizeof(struct fs_node) * nroot_nodes); 71 72 for (uint32_t i = 0; i < nroot_nodes; i++) { 73 // Edit the file's header, rn it holds the file offset relative to the start of the ramdisk 74 // We want it relative to the start of memory 75 file_headers[i].offset += location; 76 77 // Create a new file node 78 strcpy(root_nodes[i].name, file_headers[i].name); 79 root_nodes[i].mask = root_nodes[i].uid = root_nodes[i].gid = 0; 80 root_nodes[i].length = file_headers[i].length; 81 root_nodes[i].inode = i; 82 root_nodes[i].flags = FS_FILE; 83 root_nodes[i].read = &initrd_read; 84 root_nodes[i].write = 0; 85 root_nodes[i].open = 0; 86 root_nodes[i].close = 0; 87 root_nodes[i].readdir = 0; 88 root_nodes[i].finddir = 0; 89 root_nodes[i].impl = 0; 90 } 91 92 terminal_writestring("Initrd loaded with "); 93 char buf[12]; 94 itoa(nroot_nodes, buf, 10); 95 terminal_writestring(buf); 96 terminal_writestring(" files\n"); 97 98 return initrd_root; 99 }