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 +#include +#include +#include +#include + +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 + +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 #include #include -#include +#include #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 #include #include +#include #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 -#include +#include -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 #include #include -#include +#include #include #include #include @@ -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 #include #include -#include +#include 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 +#include -void stivale_load(struct echfs_file_handle *fd, char *cmdline); +void stivale_load(struct file_handle *fd, char *cmdline); #endif