Skip to content

Commit

Permalink
~ | Added an initrd to filesystem
Browse files Browse the repository at this point in the history
  • Loading branch information
BolvicBolvicovic committed Sep 16, 2024
1 parent c117eae commit b638f11
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 43 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ required :
make -C lib
make -C drivers
make -C memory
make -C filesystem

$(ISO) : $(BINARY)
grub-mkrescue -o $@ isoroot
Expand Down Expand Up @@ -50,6 +51,7 @@ fclean : clean
make -C lib fclean
make -C drivers fclean
make -C memory fclean
make -C filesystem fclean
rm -rf obj
rm -rf $(ISO)
rm -rf $(BINARY)
Expand Down
13 changes: 11 additions & 2 deletions filesystem/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ MEM = filesystem.a
VFS_SRC = vfs/vfs.c
VFS_OBJ = vfs/vfs.o

IRD_SRC = initrd/initrd.c
IRD_OBJ = initrd/initrd.o

AR = ../gcc_kfs/bin/i386-elf-ar rcs
CC = ../gcc_kfs/bin/i386-elf-gcc
FLAGS = -ffreestanding \
Expand All @@ -13,17 +16,23 @@ FLAGS = -ffreestanding \

all: $(MEM)

$(MEM): $(VFS_OBJ)
$(MEM): $(VFS_OBJ) $(IRD_OBJ)
$(AR) $@ $^

vfs/%.o: vfs/%.c
$(CC) $(FLAGS) -c $^ -o $@

vfs/%.o: vfs/%.s
initrd/%.o: initrd/%.c
$(CC) $(FLAGS) -c $^ -o $@

generator: filesystem_generator.c
gcc filesystem_generator.c -o filesystem_generator
./filesystem_generator
rm -rf filesystem_generator

clean:
rm -rf $(VFS_OBJ)
rm -rf $(IRD_OBJ)

fclean: clean
rm -rf $(MEM)
Expand Down
52 changes: 52 additions & 0 deletions filesystem/filesystem_generator.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

struct initrd_header {
uint8_t magic;
char name[64];
uint32_t offset;
uint32_t len;
};

int main(int argc, char **argv) {
int nheaders = (argc - 1) / 2;
struct initrd_header headers[64];
printf("size of headers: %ld\n", sizeof(struct initrd_header));
uint32_t off = sizeof(struct initrd_header) * 64 + sizeof(int);
size_t i;
for (i = 0; i < nheaders; i++) {
printf("writing file %s->%s at 0x%x\n", argv[i * 2 + 1], argv[i * 2 + 2], off);
strcpy(headers[i].name, argv[i * 2 + 2]);
headers[i].offset = off;
FILE* stream =fopen(argv[i * 2 + 1], "r");
if (!stream) {
printf("Error: file not found: %s\n", argv[i * 2 + 1]);
return 1;
}
fseek(stream, 0, SEEK_END);
headers[i].len = ftell(stream);
off += headers[i].len;
fclose(stream);
headers[i].magic = 0xBF;
}

FILE* wstream = fopen("./initrd.img", "w");
uint8_t* data = (uint8_t*)malloc(off);
fwrite(&nheaders, sizeof(uint32_t), 1, wstream);
fwrite(headers, sizeof(struct initrd_header), 64, wstream);

for (i = 0; i < nheaders; i++) {
FILE* stream = fopen(argv[i * 2 + 1], "r");
uint8_t* buf = (uint8_t*)malloc(headers[i].len);
fread(buf, 1, headers[i].len, stream);
fwrite(buf, 1, headers[i].len, wstream);
fclose(stream);
free(buf);
}

fclose(wstream);
free(data);
return 0;
}
102 changes: 102 additions & 0 deletions filesystem/initrd/initrd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "initrd.h"

initrd_header_t *initrd_header; // The header.
initrd_file_header_t *file_headers; // The list of file headers.
fs_node_t *initrd_root; // Our root directory node.
fs_node_t *initrd_dev; // We also add a directory node for /dev, so we can mount devfs later on.
fs_node_t *root_nodes; // List of file nodes.
int nroot_nodes; // Number of file nodes.

dir_entry_t dirent;

static uint32_t initrd_read(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
initrd_file_header_t header = file_headers[node->inode];
if (offset > header.len) return 0;
if (offset+size > header.len) size = header.len - offset;
memcpy(buffer, (uint8_t*) (header.offset + offset), size);
return size;
}

static dir_entry_t *initrd_readdir(fs_node_t *node, uint32_t index) {
if (node == initrd_root && index == 0)
{
strcpy(dirent.name, "dev");
dirent.name[3] = 0; // Make sure the string is NULL-terminated.
dirent.inode = 0;
return &dirent;
}

if (index - 1 >= nroot_nodes) return NULL;
strcpy(dirent.name, root_nodes[index-1].name);
dirent.name[strlen(root_nodes[index-1].name)] = 0; // Make sure the string is NULL-terminated.
dirent.inode = root_nodes[index-1].inode;
return &dirent;
}

static fs_node_t *initrd_finddir(fs_node_t *node, char *name) {
if (node == initrd_root && !strcmp(name, "dev")) return initrd_dev;
for (size_t i = 0; i < nroot_nodes; i++) {
if (!strcmp(name, root_nodes[i].name)) return &root_nodes[i];
}
return NULL;
}

fs_node_t *initialise_initrd( uint32_t location)
{
// Initialise the main and file header pointers and populate the root directory.
initrd_header = (initrd_header_t *)location;
file_headers = (initrd_file_header_t *) (location+sizeof(initrd_header_t));
// Initialise the root directory.
initrd_root = (fs_node_t*)kmalloc(sizeof(fs_node_t));
strcpy(initrd_root->name, "initrd");
initrd_root->permissions = initrd_root->uid = initrd_root->gid = initrd_root->inode = initrd_root->len = 0;
initrd_root->flags = FS_DIRECTORY;
initrd_root->read = 0;
initrd_root->write = 0;
initrd_root->open = 0;
initrd_root->close = 0;
initrd_root->readdir = &initrd_readdir;
initrd_root->finddir = &initrd_finddir;
initrd_root->ptr = 0;
initrd_root->impl = 0;
// Initialise the /dev directory (required!)
initrd_dev = (fs_node_t*)kmalloc(sizeof(fs_node_t));
strcpy(initrd_dev->name, "dev");
initrd_dev->permissions = initrd_dev->uid = initrd_dev->gid = initrd_dev->inode = initrd_dev->len = 0;
initrd_dev->flags = FS_DIRECTORY;
initrd_dev->read = 0;
initrd_dev->write = 0;
initrd_dev->open = 0;
initrd_dev->close = 0;
initrd_dev->readdir = &initrd_readdir;
initrd_dev->finddir = &initrd_finddir;
initrd_dev->ptr = 0;
initrd_dev->impl = 0;
// Allocate space for the files in the ramdisk
root_nodes = (fs_node_t*)kmalloc(sizeof(fs_node_t) * initrd_header->nfiles);
nroot_nodes = initrd_header->nfiles;
// For every file...
int i;
for (i = 0; i < initrd_header->nfiles; i++)
{
// Edit the file's header - currently it holds the file offset
// relative to the start of the ramdisk. We want it relative to the start
// of memory.
file_headers[i].offset += location;
// Create a new file node.
strcpy(root_nodes[i].name, &file_headers[i].name);
root_nodes[i].permissions = root_nodes[i].uid = root_nodes[i].gid = 0;
root_nodes[i].len = file_headers[i].len;
root_nodes[i].inode = i;
root_nodes[i].flags = FS_FILE;
root_nodes[i].read = &initrd_read;
root_nodes[i].write = 0;
root_nodes[i].readdir = 0;
root_nodes[i].finddir = 0;
root_nodes[i].open = 0;
root_nodes[i].close = 0;
root_nodes[i].impl = 0;
}

return initrd_root;
}
19 changes: 19 additions & 0 deletions filesystem/initrd/initrd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef INITRD_H
#define INITRD_H

#include "../vfs/vfs.h"

typedef struct {
uint32_t nfiles;
} initrd_header_t;

typedef struct {
uint8_t magic;
char name[64];
uint32_t offset;
uint32_t len;
} initrd_file_header_t;

fs_node_t *initialise_initrd(uint32_t location);

#endif
30 changes: 17 additions & 13 deletions filesystem/vfs/vfs.c
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
#include "vfs.h"

fs_node_t *fs_root = NULL;

uint32_t fs_write(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
struct fs_node_s *fs_root = NULL;

uint32_t fs_write(struct fs_node_s* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
if (!node->write) return node->write(node, offset, size, buffer);
return 0;
}

uint32_t fs_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer) {

uint32_t fs_read(struct fs_node_s* node, uint32_t offset, uint32_t size, uint8_t* buffer) {
if (!node->read) return node->read(node, offset, size, buffer);
return 0;
}

void fs_open(fs_node_t* node, uint8_t read, uint8_t write) {

void fs_open(struct fs_node_s* node, uint8_t read, uint8_t write) {
if (!node->open) (node->open(node));
}

void fs_close(fs_node_t* node) {

void fs_close(struct fs_node_s* node) {
if (!node->close) (node->close(node));
}

dir_entry_t* readdir_fs(fs_node_t* node, uint32_t index) {

dir_entry_t* readdir_fs(struct fs_node_s* node, uint32_t index) {
if (!node->readdir && (node->flags & 7 == FS_DIRECTORY)) return node->readdir(node, index);
return NULL;
}

fs_node_t* finddir_fs(fs_node_t*, char* name) {

struct fs_node_s* finddir_fs(struct fs_node_s* node, char* name) {
if (!node->finddir && (node->flags & 7 == FS_DIRECTORY)) return node->finddir(node, name);
return NULL;
}
29 changes: 17 additions & 12 deletions filesystem/vfs/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include <stdint.h>
#include <stddef.h>
#include "../../lib/string/string.h"
#include "../../memory/vmm/vmm.h"

enum fs_flags {
FS_FILE = 1,
Expand All @@ -14,6 +16,11 @@ enum fs_flags {
FS_MOUNTPOINT = 8
};

typedef uint32_t (*rw_t)(struct fs_node_s*, uint32_t, uint32_t, uint8_t*);
typedef void (*oc_t)(struct fs_node_s*);
typedef struct dir_entry_s * (*readdir_t)(struct fs_node_s*, uint32_t);
typedef struct fs_node_s * (*finddir_t)(struct fs_node_s*, char* name);

typedef struct fs_node_s {
char name[128]; // Should move it to directory node
uint32_t permissions;
Expand All @@ -33,21 +40,19 @@ typedef struct fs_node_s {
struct fs_node_s *ptr; // For symlink and mountpoint
} fs_node_t;

typedef struct {
typedef struct dir_entry_s {
char name[128];
uint32_t inode;
} dir_entry_t;

typedef uint32_t (*rw_t)(fs_node_t*, uint32_t, uint32_t, uint8_t*);
typedef void (*oc_t)(fs_node_t*);
typedef dir_entry_t * (*readdir_t)(fs_node_t*, uint32_t);
typedef fs_node_t * (*finddir_t)(fs_node_t*, char* name);

uint32_t fs_write(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer);
uint32_t fs_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer);
void fs_open(fs_node_t* node, uint8_t read, uint8_t write);
void fs_close(fs_node_t* node);
dir_entry_t* readdir_fs(fs_node_t* node, uint32_t index);
fs_node_t* finddir_fs(fs_node_t*, char* name);

uint32_t fs_write(struct fs_node_s* node, uint32_t offset, uint32_t size, uint8_t* buffer);
uint32_t fs_read(struct fs_node_s* node, uint32_t offset, uint32_t size, uint8_t* buffer);
void fs_open(struct fs_node_s* node, uint8_t read, uint8_t write);
void fs_close(struct fs_node_s* node);
dir_entry_t* readdir_fs(struct fs_node_s* node, uint32_t index);
struct fs_node_s* finddir_fs(struct fs_node_s*, char* name);

extern fs_node_t* fs_root;

#endif
20 changes: 4 additions & 16 deletions kernel/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,19 @@ void kernel_main(uint32_t magic, uint32_t addr) {
multiboot_info_t* mbi = (multiboot_info_t*)addr;
struct multiboot_mmap_entry* region = (struct multiboot_mmap_entry*) mbi->mmap_addr;
uint32_t mem_size = MAX_MEMORY_SIZE;
uint32_t initrd_location = *(uint32_t*)(mbi->mods_addr);
uint32_t initrd_end = *(uint32_t*)(mbi->mods_addr + 4);

init_current_screen(BLUE, WHITE);
term_clear();
isr_install();
init_keyboard();
init_timer(50);
init_syscall();
asm volatile(
"mov $1, %eax\n"
"int $0x80"
);
pmm_init(mem_size, &bitmap);
for (size_t i = 0; i < 15; i++) {
if (region[i].type > 5) region[i].type = MULTIBOOT_MEMORY_AVAILABLE;
if (i > 0 && region[i].addr_low == 0) break;
printf ("region %d: start: %p length (bytes): %p type: %d (%s)\n", i,
region[i].addr_low,
region[i].len_low,
region[i].type, strMemoryTypes[region[i].type-1]);
if (region[i].type == MULTIBOOT_MEMORY_AVAILABLE) pmm_init_region(region[i].addr_low, region[i].len_low);
}
pmm_deinit_region(0x100000, 0);
Expand All @@ -60,12 +54,6 @@ void kernel_main(uint32_t magic, uint32_t addr) {
asm volatile("mov %%cr0, %0" : "=r" (cr0));
if (cr0 & 0x80000000) printf("Paging enabled: cr0 == %p\n", cr0);
else printf("Paging disabled: cr0 == %p\n", cr0);
uint8_t* test = kmalloc(1);
void* test2 = kmalloc(1);
*test = 5;
uint16_t* test3 = kmalloc(16);
*test3 = 6;
printf("test: %p sizeof(test) == %d bytes and value %d\n", test, kget_size(test), *test);
kfree(test);
printf("test %p | test2 %p | test3 %p\n", test, test2, test3);
if (!mbi->mods_count) printf("no mods added\n");
fs_root = initialise_initrd(initrd_location);
}
1 change: 1 addition & 0 deletions kernel/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
#include "../multiboot/multiboot.h"
#include "../memory/pmm/pmm.h"
#include "../memory/vmm/vmm.h"
#include "../filesystem/initrd/initrd.h"
#endif

0 comments on commit b638f11

Please sign in to comment.