mirror of
https://github.com/limine-bootloader/limine
synced 2024-11-27 02:49:56 +03:00
Add file handle abstractions
This commit is contained in:
parent
680d683cd0
commit
d2c4773c6d
@ -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;
|
||||
|
||||
|
@ -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
34
src/fs/file.c
Normal 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
17
src/fs/file.h
Normal 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
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user