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, §ion, hdr.shoff + i * sizeof(struct elf_shdr),
+ fread(fd, §ion, 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
