:: commit d2c4773c6decb12a9eb30863849357804128d9b8

mintsuki <mintsuki@protonmail.com> — 2020-04-14 03:20

parents: 680d683cd0

Add file handle abstractions

diff --git a/src/fs/echfs.c b/src/fs/echfs.c
index 3196a11d..2998fbf7 100644
--- a/src/fs/echfs.c
+++ b/src/fs/echfs.c
@@ -50,6 +50,20 @@ int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t
     return 0;
 }
 
+int echfs_check_signature(int disk, int partition) {
+    struct mbr_part mbr_part;
+    mbr_get_part(&mbr_part, disk, partition);
+
+    struct echfs_identity_table id_table;
+    read_partition(disk, &mbr_part, &id_table, 0, sizeof(struct echfs_identity_table));
+
+    if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
+        return 0;
+    }
+
+    return 1;
+}
+
 int echfs_open(struct echfs_file_handle *ret, int disk, int partition, const char *filename) {
     ret->disk = disk;
 
diff --git a/src/fs/echfs.h b/src/fs/echfs.h
index 369212de..fe096612 100644
--- a/src/fs/echfs.h
+++ b/src/fs/echfs.h
@@ -30,6 +30,8 @@ struct echfs_file_handle {
     struct echfs_dir_entry dir_entry;
 };
 
+int echfs_check_signature(int disk, int partition);
+
 int echfs_open(struct echfs_file_handle *ret, int disk, int partition, const char *filename);
 int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t count);
 
diff --git a/src/fs/file.c b/src/fs/file.c
new file mode 100644
index 00000000..da06aa2a
--- /dev/null
+++ b/src/fs/file.c
@@ -0,0 +1,34 @@
+#include <stddef.h>
+#include <stdint.h>
+#include <fs/file.h>
+#include <fs/echfs.h>
+#include <lib/blib.h>
+
+int fopen(struct file_handle *ret, int disk, int partition, const char *filename) {
+    if (echfs_check_signature(disk, partition)) {
+        struct echfs_file_handle *fd = balloc(sizeof(struct echfs_file_handle));
+
+        int r = echfs_open(fd, disk, partition, filename);
+        if (r)
+            return r;
+
+        ret->fd        = (void *)fd;
+        ret->read      = (void *)echfs_read;
+        ret->disk      = disk;
+        ret->partition = partition;
+        ret->size      = fd->dir_entry.size;
+
+        return 0;
+    }
+
+    // Append other FS checks here
+
+    print("fs: Could not determine the file system of disk %u partition %u",
+          disk, partition);
+
+    return -1;
+}
+
+int fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count) {
+    return fd->read(fd->fd, buf, loc, count);
+}
diff --git a/src/fs/file.h b/src/fs/file.h
new file mode 100644
index 00000000..d39ec2a9
--- /dev/null
+++ b/src/fs/file.h
@@ -0,0 +1,17 @@
+#ifndef __FS__FILE_H__
+#define __FS__FILE_H__
+
+#include <stdint.h>
+
+struct file_handle {
+    int        disk;
+    int        partition;
+    void      *fd;
+    int      (*read)(void *fd, void *buf, uint64_t loc, uint64_t count);
+    uint64_t   size;
+};
+
+int fopen(struct file_handle *ret, int disk, int partition, const char *filename);
+int fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count);
+
+#endif
diff --git a/src/lib/config.c b/src/lib/config.c
index c48e0247..c429b450 100644
--- a/src/lib/config.c
+++ b/src/lib/config.c
@@ -2,7 +2,7 @@
 #include <lib/config.h>
 #include <lib/libc.h>
 #include <lib/blib.h>
-#include <fs/echfs.h>
+#include <fs/file.h>
 
 #define SEPARATOR '\n'
 #define CONFIG_NAME "qloader2.cfg"
@@ -11,13 +11,13 @@
 static char *config_addr;
 
 int init_config(int drive, int part) {
-    struct echfs_file_handle f;
+    struct file_handle f;
 
-    if (echfs_open(&f, drive, part, CONFIG_NAME)) {
+    if (fopen(&f, drive, part, CONFIG_NAME)) {
         return -1;
     }
 
-    if (f.dir_entry.size >= MAX_CONFIG_SIZE) {
+    if (f.size >= MAX_CONFIG_SIZE) {
         print("Config file is too big!\n");
         for (;;);
     }
@@ -25,7 +25,7 @@ int init_config(int drive, int part) {
     config_addr = balloc(MAX_CONFIG_SIZE);
     memset(config_addr, 0, MAX_CONFIG_SIZE);
 
-    echfs_read(&f, config_addr, 0, f.dir_entry.size);
+    fread(&f, config_addr, 0, f.size);
 
     return 0;
 }
diff --git a/src/lib/elf.c b/src/lib/elf.c
index 063c0ddf..dd67078c 100644
--- a/src/lib/elf.c
+++ b/src/lib/elf.c
@@ -3,6 +3,7 @@
 #include <lib/blib.h>
 #include <lib/libc.h>
 #include <lib/elf.h>
+#include <fs/file.h>
 
 #define PT_LOAD     0x00000001
 #define PT_INTERP   0x00000003
@@ -59,9 +60,9 @@ struct elf_shdr {
     uint64_t   sh_entsize;
 };
 
-int elf_load_section(struct echfs_file_handle *fd, void *buffer, const char *name, size_t limit) {
+int elf_load_section(struct file_handle *fd, void *buffer, const char *name, size_t limit) {
     struct elf_hdr hdr;
-    echfs_read(fd, &hdr, 0, sizeof(struct elf_hdr));
+    fread(fd, &hdr, 0, sizeof(struct elf_hdr));
 
     if (strncmp((char *)hdr.ident, "\177ELF", 4)) {
         print("elf: Not a valid ELF file.\n");
@@ -79,21 +80,21 @@ int elf_load_section(struct echfs_file_handle *fd, void *buffer, const char *nam
     }
 
     struct elf_shdr shstrtab;
-    echfs_read(fd, &shstrtab, hdr.shoff + hdr.shstrndx * sizeof(struct elf_shdr),
+    fread(fd, &shstrtab, hdr.shoff + hdr.shstrndx * sizeof(struct elf_shdr),
             sizeof(struct elf_shdr));
 
     char names[shstrtab.sh_size];
-    echfs_read(fd, names, shstrtab.sh_offset, shstrtab.sh_size);
+    fread(fd, names, shstrtab.sh_offset, shstrtab.sh_size);
 
     for (uint16_t i = 0; i < hdr.sh_num; i++) {
         struct elf_shdr section;
-        echfs_read(fd, &section, hdr.shoff + i * sizeof(struct elf_shdr),
+        fread(fd, &section, hdr.shoff + i * sizeof(struct elf_shdr),
                    sizeof(struct elf_shdr));
 
         if (!strcmp(&names[section.sh_name], name)) {
             if (section.sh_size > limit)
                 return 3;
-            echfs_read(fd, buffer, section.sh_offset, section.sh_size);
+            fread(fd, buffer, section.sh_offset, section.sh_size);
             return 0;
         }
     }
@@ -103,9 +104,9 @@ int elf_load_section(struct echfs_file_handle *fd, void *buffer, const char *nam
 
 #define FIXED_HIGHER_HALF_OFFSET ((uint64_t)0xffffffff80000000)
 
-int elf_load(struct echfs_file_handle *fd, uint64_t *entry_point, uint64_t *top) {
+int elf_load(struct file_handle *fd, uint64_t *entry_point, uint64_t *top) {
     struct elf_hdr hdr;
-    echfs_read(fd, &hdr, 0, sizeof(struct elf_hdr));
+    fread(fd, &hdr, 0, sizeof(struct elf_hdr));
 
     if (strncmp((char *)hdr.ident, "\177ELF", 4)) {
         print("Not a valid ELF file.\n");
@@ -126,7 +127,7 @@ int elf_load(struct echfs_file_handle *fd, uint64_t *entry_point, uint64_t *top)
 
     for (uint16_t i = 0; i < hdr.ph_num; i++) {
         struct elf_phdr phdr;
-        echfs_read(fd, &phdr, hdr.phoff + i * sizeof(struct elf_phdr),
+        fread(fd, &phdr, hdr.phoff + i * sizeof(struct elf_phdr),
                    sizeof(struct elf_phdr));
 
         if (phdr.p_type != PT_LOAD)
@@ -139,7 +140,7 @@ int elf_load(struct echfs_file_handle *fd, uint64_t *entry_point, uint64_t *top)
         if (this_top > *top)
             *top = this_top;
 
-        echfs_read(fd, (void *)(uint32_t)phdr.p_vaddr,
+        fread(fd, (void *)(uint32_t)phdr.p_vaddr,
                    phdr.p_offset, phdr.p_filesz);
 
         size_t to_zero = (size_t)(phdr.p_memsz - phdr.p_filesz);
diff --git a/src/lib/elf.h b/src/lib/elf.h
index f8433b0c..85b57845 100644
--- a/src/lib/elf.h
+++ b/src/lib/elf.h
@@ -2,9 +2,9 @@
 #define __LIB__ELF_H__
 
 #include <stdint.h>
-#include <fs/echfs.h>
+#include <fs/file.h>
 
-int elf_load(struct echfs_file_handle *fd, uint64_t *entry_point, uint64_t *top);
-int elf_load_section(struct echfs_file_handle *fd, void *buffer, const char *name, size_t limit);
+int elf_load(struct file_handle *fd, uint64_t *entry_point, uint64_t *top);
+int elf_load_section(struct file_handle *fd, void *buffer, const char *name, size_t limit);
 
 #endif
diff --git a/src/main.c b/src/main.c
index f84a048a..a7e76cb6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -11,7 +11,7 @@ asm (
 #include <lib/libc.h>
 #include <lib/mbr.h>
 #include <lib/config.h>
-#include <fs/echfs.h>
+#include <fs/file.h>
 #include <sys/interrupt.h>
 #include <lib/elf.h>
 #include <protos/stivale.h>
@@ -22,7 +22,7 @@ extern symbol bss_end;
 static int config_loaded = 0;
 
 void main(int boot_drive) {
-    struct echfs_file_handle f;
+    struct file_handle f;
 
     // Zero out .bss section
     for (uint8_t *p = bss_begin; p < bss_end; p++)
@@ -36,7 +36,6 @@ void main(int boot_drive) {
     print("qLoader 2\n\n");
     print("=> Boot drive: %x\n", boot_drive);
 
-
     // Enumerate partitions.
     struct mbr_part parts[4];
     for (int i = 0; i < 4; i++) {
@@ -92,12 +91,12 @@ void main(int boot_drive) {
     }
     print("\n");
 
-    echfs_open(&f, drive, part, path);
+    fopen(&f, drive, part, path);
 
     if (!strcmp(proto, "stivale")) {
         stivale_load(&f, cmdline);
     } else if (!strcmp(proto, "qword")) {
-        echfs_read(&f, (void *)0x100000, 0, f.dir_entry.size);
+        fread(&f, (void *)0x100000, 0, f.size);
         // Boot the kernel.
         asm volatile (
             "cli\n\t"
diff --git a/src/protos/stivale.c b/src/protos/stivale.c
index ac8768cc..30366562 100644
--- a/src/protos/stivale.c
+++ b/src/protos/stivale.c
@@ -7,7 +7,7 @@
 #include <lib/e820.h>
 #include <lib/config.h>
 #include <drivers/vbe.h>
-#include <fs/echfs.h>
+#include <fs/file.h>
 
 struct stivale_header {
     uint64_t stack;
@@ -40,7 +40,7 @@ struct stivale_struct {
 
 struct stivale_struct stivale_struct = {0};
 
-void stivale_load(struct echfs_file_handle *fd, char *cmdline) {
+void stivale_load(struct file_handle *fd, char *cmdline) {
     uint64_t entry_point;
 
     struct stivale_header stivale_hdr;
@@ -89,17 +89,17 @@ void stivale_load(struct echfs_file_handle *fd, char *cmdline) {
             part = (int)strtoui(buf);
         }
 
-        struct echfs_file_handle f;
-        echfs_open(&f, fd->disk, part, module_file);
+        struct file_handle f;
+        fopen(&f, fd->disk, part, module_file);
 
         void *module_addr = (void *)(((uint32_t)top_used_addr & 0xfff) ?
             ((uint32_t)top_used_addr & ~((uint32_t)0xfff)) + 0x1000 :
             (uint32_t)top_used_addr);
 
-        echfs_read(&f, module_addr, 0, f.dir_entry.size);
+        fread(&f, module_addr, 0, f.size);
 
         m->begin = (uint64_t)(size_t)module_addr;
-        m->end   = m->begin + f.dir_entry.size;
+        m->end   = m->begin + f.size;
         m->next  = 0;
 
         top_used_addr = (uint64_t)(size_t)m->end;
diff --git a/src/protos/stivale.h b/src/protos/stivale.h
index 2f471945..0c7fd40d 100644
--- a/src/protos/stivale.h
+++ b/src/protos/stivale.h
@@ -1,8 +1,8 @@
 #ifndef __PROTOS__STIVALE_H__
 #define __PROTOS__STIVALE_H__
 
-#include <fs/echfs.h>
+#include <fs/file.h>
 
-void stivale_load(struct echfs_file_handle *fd, char *cmdline);
+void stivale_load(struct file_handle *fd, char *cmdline);
 
 #endif
tab: 248 wrap: offon