aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2019-10-30 16:02:10 +0100
committerMarvin Borner2019-10-30 16:02:10 +0100
commit118898807865ba11f5d7754f6f0572a0403f8512 (patch)
tree0b69c881089d659ebb214c409b699cc06323ab3d
parentfd4f0a11126a20e75d72f8f2e6d418598fd5f37d (diff)
Started implementation of initrd based vfs
-rw-r--r--Makefile16
-rw-r--r--src/kernel/acpi/acpi.c6
-rw-r--r--src/kernel/boot.asm7
-rw-r--r--src/kernel/commands/command.c2
-rw-r--r--src/kernel/fs/initrd.c104
-rw-r--r--src/kernel/fs/initrd.h20
-rw-r--r--src/kernel/fs/vfs.c43
-rw-r--r--src/kernel/fs/vfs.h65
-rw-r--r--src/kernel/graphics/vesa.c2
-rw-r--r--src/kernel/interrupts/idt.c2
-rw-r--r--src/kernel/kernel.c14
-rw-r--r--src/kernel/lib/lib.h6
-rw-r--r--src/kernel/lib/memory.c6
-rw-r--r--src/kernel/mutliboot.h47
-rw-r--r--src/kernel/paging/paging.c2
-rw-r--r--src/kernel/system.h5
-rw-r--r--src/utils/make_initrd.c51
-rw-r--r--src/utils/test.txt1
18 files changed, 383 insertions, 16 deletions
diff --git a/Makefile b/Makefile
index 6773be9..9f28fbb 100644
--- a/Makefile
+++ b/Makefile
@@ -43,6 +43,22 @@ build: clean
cp ./src/kernel/grub.cfg ./iso/boot/grub/; \
grub-mkrescue -o ./build/melvix.iso ./iso/;
+image: build
+ @set -e; \
+ gcc -w ./src/utils/make_initrd.c -o ./build/make_initrd || exit; \
+ ./build/make_initrd ./src/utils/test.txt test.txt || exit; \
+ mv initrd.img ./build/initrd.img || exit; \
+ dd if=/dev/zero of=./build/image.img iflag=fullblock bs=1M count=10 && sync; \
+ mkfs.ext2 ./build/image.img; \
+ device=$$(sudo losetup -f); \
+ sudo losetup $$device ./build/image.img || exit; \
+ mkdir ./build/mnt/ || exit; \
+ sudo mount $$device ./build/mnt/ || exit; \
+ sudo cp ./build/melvix.iso ./build/mnt/kernel || exit; \
+ sudo cp ./build/initrd.img ./build/mnt/initrd || exit; \
+ sudo umount $$device || exit; \
+ sudo losetup -d $$device;
+
cross:
@set -e; \
[ -d "./cross/" ] && echo "Please remove ./cross/ and try again" && exit; \
diff --git a/src/kernel/acpi/acpi.c b/src/kernel/acpi/acpi.c
index 24da496..e0d260b 100644
--- a/src/kernel/acpi/acpi.c
+++ b/src/kernel/acpi/acpi.c
@@ -24,7 +24,7 @@ unsigned int *acpi_check_rsd_ptr(unsigned int *ptr) {
char check = 0;
unsigned int i;
- if (memory_compare(sig, rsdp, 8) == 0) {
+ if (memcmp(sig, rsdp, 8) == 0) {
bptr = (char *) ptr;
for (i = 0; i < sizeof(struct RSDPtr); i++) {
check += *bptr;
@@ -62,7 +62,7 @@ unsigned int *acpi_get_rsd_ptr() {
}
int acpi_check_header(unsigned int *ptr, char *sig) {
- if (memory_compare(ptr, sig, 4) == 0) {
+ if (memcmp(ptr, sig, 4) == 0) {
char *checkPtr = (char *) ptr;
int len = *(ptr + 1);
char check = 0;
@@ -122,7 +122,7 @@ int acpi_install() {
char *S5Addr = (char *) facp->DSDT + 36;
int dsdt_length = *(facp->DSDT + 1) - 36;
while (0 < dsdt_length--) {
- if (memory_compare(S5Addr, "_S5_", 4) == 0)
+ if (memcmp(S5Addr, "_S5_", 4) == 0)
break;
S5Addr++;
}
diff --git a/src/kernel/boot.asm b/src/kernel/boot.asm
index d533307..fad05ff 100644
--- a/src/kernel/boot.asm
+++ b/src/kernel/boot.asm
@@ -30,8 +30,13 @@ mboot:
dd start
; Endless loop
+extern kernel_main
stublet:
- extern kernel_main
+ ; Load multiboot information
+ push esp
+ push ebx
+
+ cli
call kernel_main
jmp $
diff --git a/src/kernel/commands/command.c b/src/kernel/commands/command.c
index 2334219..1118b29 100644
--- a/src/kernel/commands/command.c
+++ b/src/kernel/commands/command.c
@@ -8,7 +8,7 @@
int32_t starts_with(const char *a, const char *b) {
size_t length_pre = strlen(b);
size_t length_main = strlen(a);
- return length_main < length_pre ? 0 : memory_compare(b, a, length_pre) == 0;
+ return length_main < length_pre ? 0 : memcmp(b, a, length_pre) == 0;
}
void exec_command(char *command) {
diff --git a/src/kernel/fs/initrd.c b/src/kernel/fs/initrd.c
new file mode 100644
index 0000000..b291801
--- /dev/null
+++ b/src/kernel/fs/initrd.c
@@ -0,0 +1,104 @@
+#include <stdint.h>
+#include <kernel/fs/initrd.h>
+#include <kernel/fs/vfs.h>
+#include <kernel/lib/lib.h>
+#include <kernel/lib/alloc.h>
+
+initrd_header_t *initrd_header;
+initrd_file_header_t *file_headers;
+fs_node_t *initrd_root;
+fs_node_t *initrd_dev;
+fs_node_t *root_nodes;
+int nroot_nodes;
+
+struct dirent 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.length)
+ return 0;
+ if (offset + size > header.length)
+ size = header.length - offset;
+ memcpy(buffer, (uint8_t *) (header.offset + offset), size);
+ return size;
+}
+
+static struct dirent *initrd_readdir(fs_node_t *node, uint32_t index) {
+ if (node == initrd_root && index == 0) {
+ strcpy(dirent.name, "dev");
+ dirent.name[3] = 0;
+ dirent.ino = 0;
+ return &dirent;
+ }
+
+ if (index - 1 >= nroot_nodes)
+ return 0;
+ strcpy(dirent.name, root_nodes[index - 1].name);
+ dirent.name[strlen(root_nodes[index - 1].name)] = 0;
+ dirent.ino = 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;
+
+ int i;
+ for (i = 0; i < nroot_nodes; i++)
+ if (!strcmp(name, root_nodes[i].name))
+ return &root_nodes[i];
+ return 0;
+}
+
+fs_node_t *initialise_initrd(uint32_t location) {
+ initrd_header = (initrd_header_t *) location;
+ file_headers = (initrd_file_header_t *) (location + sizeof(initrd_header_t));
+
+ initrd_root = (fs_node_t *) kmalloc(sizeof(fs_node_t));
+ strcpy(initrd_root->name, "initrd");
+ initrd_root->mask = initrd_root->uid = initrd_root->gid = initrd_root->inode = initrd_root->length = 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;
+
+ initrd_dev = (fs_node_t *) kmalloc(sizeof(fs_node_t));
+ strcpy(initrd_dev->name, "dev");
+ initrd_dev->mask = initrd_dev->uid = initrd_dev->gid = initrd_dev->inode = initrd_dev->length = 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;
+
+ root_nodes = (fs_node_t *) kmalloc(sizeof(fs_node_t) * initrd_header->nfiles);
+ nroot_nodes = initrd_header->nfiles;
+
+ for (int i = 0; i < initrd_header->nfiles; i++) {
+ file_headers[i].offset += location;
+
+ strcpy(root_nodes[i].name, &file_headers[i].name);
+ root_nodes[i].mask = root_nodes[i].uid = root_nodes[i].gid = 0;
+ root_nodes[i].length = file_headers[i].length;
+ 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;
+}
diff --git a/src/kernel/fs/initrd.h b/src/kernel/fs/initrd.h
new file mode 100644
index 0000000..10dec22
--- /dev/null
+++ b/src/kernel/fs/initrd.h
@@ -0,0 +1,20 @@
+#ifndef MELVIX_INITRD_H
+#define MELVIX_INITRD_H
+
+#include <stdint.h>
+#include <kernel/fs/vfs.h>
+
+typedef struct {
+ uint32_t nfiles;
+} initrd_header_t;
+
+typedef struct {
+ uint8_t magic;
+ int8_t name[64];
+ uint32_t offset;
+ uint32_t length;
+} initrd_file_header_t;
+
+fs_node_t *initialise_initrd(uint32_t location);
+
+#endif
diff --git a/src/kernel/fs/vfs.c b/src/kernel/fs/vfs.c
new file mode 100644
index 0000000..5591a60
--- /dev/null
+++ b/src/kernel/fs/vfs.c
@@ -0,0 +1,43 @@
+#include <kernel/fs/vfs.h>
+
+fs_node_t *fs_root = 0;
+
+uint32_t read_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
+ if (node->read != 0)
+ return node->read(node, offset, size, buffer);
+ else
+ return 0;
+}
+
+uint32_t write_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) {
+ if (node->write != 0)
+ return node->write(node, offset, size, buffer);
+ else
+ return 0;
+}
+
+void open_fs(fs_node_t *node, uint8_t read, uint8_t write) {
+ if (node->open != 0)
+ return node->open(node);
+}
+
+void close_fs(fs_node_t *node) {
+ if (node->close != 0)
+ return node->close(node);
+}
+
+struct dirent *readdir_fs(fs_node_t *node, uint32_t index) {
+ if ((node->flags & 0x7) == FS_DIRECTORY &&
+ node->readdir != 0)
+ return node->readdir(node, index);
+ else
+ return 0;
+}
+
+fs_node_t *finddir_fs(fs_node_t *node, char *name) {
+ if ((node->flags & 0x7) == FS_DIRECTORY &&
+ node->finddir != 0)
+ return node->finddir(node, name);
+ else
+ return 0;
+}
diff --git a/src/kernel/fs/vfs.h b/src/kernel/fs/vfs.h
new file mode 100644
index 0000000..5a72861
--- /dev/null
+++ b/src/kernel/fs/vfs.h
@@ -0,0 +1,65 @@
+#ifndef MELVIX_VFS_H
+#define MELVIX_VFS_H
+
+#include <stdint.h>
+
+#define FS_FILE 0x01
+#define FS_DIRECTORY 0x02
+#define FS_CHARDEVICE 0x03
+#define FS_BLOCKDEVICE 0x04
+#define FS_PIPE 0x05
+#define FS_SYMLINK 0x06
+#define FS_MOUNTPOINT 0x08
+
+struct fs_node;
+
+typedef uint32_t (*read_type_t)(struct fs_node *, uint32_t, uint32_t, uint8_t *);
+
+typedef uint32_t (*write_type_t)(struct fs_node *, uint32_t, uint32_t, uint8_t *);
+
+typedef void (*open_type_t)(struct fs_node *);
+
+typedef void (*close_type_t)(struct fs_node *);
+
+typedef struct dirent *(*readdir_type_t)(struct fs_node *, uint32_t);
+
+typedef struct fs_node *(*finddir_type_t)(struct fs_node *, char *name);
+
+typedef struct fs_node {
+ char name[128];
+ uint32_t mask;
+ uint32_t uid;
+ uint32_t gid;
+ uint32_t flags;
+ uint32_t inode;
+ uint32_t length;
+ uint32_t impl;
+ read_type_t read;
+ write_type_t write;
+ open_type_t open;
+ close_type_t close;
+ readdir_type_t readdir;
+ finddir_type_t finddir;
+ struct fs_node *ptr;
+} fs_node_t;
+
+struct dirent {
+ char name[128];
+ uint32_t ino;
+};
+
+extern fs_node_t *fs_root;
+
+uint32_t read_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer);
+
+uint32_t write_fs(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer);
+
+void open_fs(fs_node_t *node, uint8_t read, uint8_t write);
+
+void close_fs(fs_node_t *node);
+
+struct dirent *readdir_fs(fs_node_t *node, uint32_t index);
+
+fs_node_t *finddir_fs(fs_node_t *node, char *name);
+
+#endif
diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c
index 8347c56..94f53c6 100644
--- a/src/kernel/graphics/vesa.c
+++ b/src/kernel/graphics/vesa.c
@@ -309,7 +309,7 @@ void vesa_keyboard_char(char ch) {
} else if (ch == '\n') {
vesa_draw_char(ch);
exec_command(text);
- memory_set(text, 0, sizeof(text));
+ memset(text, 0, sizeof(text));
// terminal_scroll();
} else if (ch >= ' ') {
vesa_draw_char(ch);
diff --git a/src/kernel/interrupts/idt.c b/src/kernel/interrupts/idt.c
index 26489c4..5f92294 100644
--- a/src/kernel/interrupts/idt.c
+++ b/src/kernel/interrupts/idt.c
@@ -39,7 +39,7 @@ void idt_install() {
idtp.base = &idt;
// Clear IDT by setting memory cells to 0
- memory_set(&idt, 0, sizeof(struct idt_entry) * 256);
+ memset(&idt, 0, sizeof(struct idt_entry) * 256);
idt_load();
vga_log("Installed Interrupt Descriptor Table", 6);
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index 75867a8..cba4f6e 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -6,6 +6,8 @@
#include <kernel/paging/paging.h>
#include <kernel/input/input.h>
#include <kernel/acpi/acpi.h>
+#include <kernel/mutliboot.h>
+#include <kernel/fs/initrd.h>
void init() {
vga_log("Installing basic features of Melvix...", 0);
@@ -25,9 +27,19 @@ void init() {
asm volatile ("sti");
}
-void kernel_main(void) {
+void kernel_main(struct multiboot *mboot_ptr) {
init();
+ info("Kernel size in KiB: ");
+ vesa_draw_number((int) end >> 10);
+
+ assert(mboot_ptr->mods_count > 0);
+ uint32_t initrd_location = *((uint32_t *) mboot_ptr->mods_addr);
+ uint32_t initrd_end = *(uint32_t *) (mboot_ptr->mods_addr + 4);
+ // Don't trample our module with placement accesses, please!
+ // placement_address = initrd_end;
+ fs_root = initialise_initrd(initrd_location);
+
// asm volatile ("div %0" :: "r"(0)); // Exception testing x/0
loop:
asm volatile ("hlt");
diff --git a/src/kernel/lib/lib.h b/src/kernel/lib/lib.h
index de09e0f..420dd5b 100644
--- a/src/kernel/lib/lib.h
+++ b/src/kernel/lib/lib.h
@@ -39,7 +39,7 @@ void strcpy(char *dest, const char *src);
* @param count The number of bytes to be copied (src)
* @return The modified dest pointer
*/
-void *memory_copy(void *dest, const void *src, size_t count);
+void *memcpy(void *dest, const void *src, size_t count);
/**
* Replace n bytes of dest by val
@@ -48,7 +48,7 @@ void *memory_copy(void *dest, const void *src, size_t count);
* @param count The number of times val should replace dest entry
* @return The modified dest pointer
*/
-void *memory_set(void *dest, char val, size_t count);
+void *memset(void *dest, char val, size_t count);
/**
* Compare the first n bytes of a and b
@@ -57,6 +57,6 @@ void *memory_set(void *dest, char val, size_t count);
* @param size The number of bytes to be compared
* @return -1 if a < b, 0 if a = b and 1 if a > b
*/
-int memory_compare(const void *a_ptr, const void *b_ptr, size_t size);
+int memcmp(const void *a_ptr, const void *b_ptr, size_t size);
#endif
diff --git a/src/kernel/lib/memory.c b/src/kernel/lib/memory.c
index 6ec4ed9..a030c9a 100644
--- a/src/kernel/lib/memory.c
+++ b/src/kernel/lib/memory.c
@@ -1,19 +1,19 @@
#include <stddef.h>
-void *memory_copy(void *dest, const void *src, size_t count) {
+void *memcpy(void *dest, const void *src, size_t count) {
const char *sp = (const char *) src;
char *dp = (char *) dest;
for (; count != 0; count--) *dp++ = *sp++;
return dest;
}
-void *memory_set(void *dest, char val, size_t count) {
+void *memset(void *dest, char val, size_t count) {
char *temp = (char *) dest;
for (; count != 0; count--) *temp++ = val;
return dest;
}
-int memory_compare(const void *a_ptr, const void *b_ptr, size_t size) {
+int memcmp(const void *a_ptr, const void *b_ptr, size_t size) {
const unsigned char *a = (const unsigned char *) a_ptr;
const unsigned char *b = (const unsigned char *) b_ptr;
for (size_t i = 0; i < size; i++) {
diff --git a/src/kernel/mutliboot.h b/src/kernel/mutliboot.h
new file mode 100644
index 0000000..683f95f
--- /dev/null
+++ b/src/kernel/mutliboot.h
@@ -0,0 +1,47 @@
+#ifndef MELVIX_MUTLIBOOT_H
+#define MELVIX_MUTLIBOOT_H
+
+#include <stdint.h>
+
+#define MULTIBOOT_FLAG_MEM 0x001
+#define MULTIBOOT_FLAG_DEVICE 0x002
+#define MULTIBOOT_FLAG_CMDLINE 0x004
+#define MULTIBOOT_FLAG_MODS 0x008
+#define MULTIBOOT_FLAG_AOUT 0x010
+#define MULTIBOOT_FLAG_ELF 0x020
+#define MULTIBOOT_FLAG_MMAP 0x040
+#define MULTIBOOT_FLAG_CONFIG 0x080
+#define MULTIBOOT_FLAG_LOADER 0x100
+#define MULTIBOOT_FLAG_APM 0x200
+#define MULTIBOOT_FLAG_VBE 0x400
+
+struct multiboot {
+ uint32_t flags;
+ uint32_t mem_lower;
+ uint32_t mem_upper;
+ uint32_t boot_device;
+ uint32_t cmdline;
+ uint32_t mods_count;
+ uint32_t mods_addr;
+ uint32_t num;
+ uint32_t size;
+ uint32_t addr;
+ uint32_t shndx;
+ uint32_t mmap_length;
+ uint32_t mmap_addr;
+ uint32_t drives_length;
+ uint32_t drives_addr;
+ uint32_t config_table;
+ uint32_t boot_loader_name;
+ uint32_t apm_table;
+ uint32_t vbe_control_info;
+ uint32_t vbe_mode_info;
+ uint32_t vbe_mode;
+ uint32_t vbe_interface_seg;
+ uint32_t vbe_interface_off;
+ uint32_t vbe_interface_len;
+} __attribute__((packed));
+
+typedef struct multiboot_header multiboot_header_t;
+
+#endif
diff --git a/src/kernel/paging/paging.c b/src/kernel/paging/paging.c
index 02fc253..bb3b1df 100644
--- a/src/kernel/paging/paging.c
+++ b/src/kernel/paging/paging.c
@@ -2,8 +2,6 @@
#include <kernel/paging/paging.h>
#include <kernel/system.h>
-extern void *end;
-
uint32_t page_directory[1024] __attribute__((aligned(4096)));
uint32_t page_tables[1024][1024] __attribute__((aligned(4096)));
diff --git a/src/kernel/system.h b/src/kernel/system.h
index e6888fc..d431a9e 100644
--- a/src/kernel/system.h
+++ b/src/kernel/system.h
@@ -2,6 +2,11 @@
#define MELVIX_SYSTEM_H
/**
+ * The kernel end
+ */
+extern void *end;
+
+/**
* Initialize the basic features of the OS
*/
void init();
diff --git a/src/utils/make_initrd.c b/src/utils/make_initrd.c
new file mode 100644
index 0000000..f6e504b
--- /dev/null
+++ b/src/utils/make_initrd.c
@@ -0,0 +1,51 @@
+#include <stdio.h>
+
+struct initrd_header {
+ unsigned char magic;
+ char name[64];
+ unsigned int offset;
+ unsigned int length;
+};
+
+int main(char argc, char **argv) {
+ int nheaders = (argc - 1) / 2;
+ struct initrd_header headers[64];
+ printf("size of header: %d\n", sizeof(struct initrd_header));
+ unsigned int off = sizeof(struct initrd_header) * 64 + sizeof(int);
+
+ for (int 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].name[strlen(argv[i * 2 + 2])] = '\0';
+ headers[i].offset = off;
+ FILE *stream = fopen(argv[i * 2 + 1], "r");
+ if (stream == 0) {
+ printf("Error: file not found: %s\n", argv[i * 2 + 1]);
+ return 1;
+ }
+ fseek(stream, 0, SEEK_END);
+ headers[i].length = ftell(stream);
+ off += headers[i].length;
+ fclose(stream);
+ headers[i].magic = 0xBF;
+ }
+
+ FILE *wstream = fopen("./initrd.img", "w");
+ unsigned char *data = (unsigned char *) malloc(off);
+ fwrite(&nheaders, sizeof(int), 1, wstream);
+ fwrite(headers, sizeof(struct initrd_header), 64, wstream);
+
+ for (int i = 0; i < nheaders; i++) {
+ FILE *stream = fopen(argv[i * 2 + 1], "r");
+ unsigned char *buf = (unsigned char *) malloc(headers[i].length);
+ fread(buf, 1, headers[i].length, stream);
+ fwrite(buf, 1, headers[i].length, wstream);
+ fclose(stream);
+ free(buf);
+ }
+
+ fclose(wstream);
+ free(data);
+
+ return 0;
+}
diff --git a/src/utils/test.txt b/src/utils/test.txt
new file mode 100644
index 0000000..9116450
--- /dev/null
+++ b/src/utils/test.txt
@@ -0,0 +1 @@
+heey