Add file handle abstractions

This commit is contained in:
mintsuki 2020-04-14 05:20:55 +02:00
parent 680d683cd0
commit d2c4773c6d
10 changed files with 98 additions and 31 deletions

View File

@ -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;

View File

@ -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);

34
src/fs/file.c Normal file
View File

@ -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);
}

17
src/fs/file.h Normal file
View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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"

View File

@ -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;

View File

@ -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