From 84ac96435e7ae183644830c02a22cefec62f8f80 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Sat, 28 Mar 2020 04:02:26 +0100 Subject: [PATCH] Add bump allocator --- src/drivers/disk.c | 15 +++++++++------ src/fs/echfs.c | 7 +++---- src/fs/echfs.h | 1 + src/lib/blib.c | 19 +++++++++++++++++++ src/lib/blib.h | 3 +++ src/main.c | 16 +++++++++------- src/protos/stivale.c | 5 +++-- 7 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/drivers/disk.c b/src/drivers/disk.c index f94e1488..0aebbab1 100644 --- a/src/drivers/disk.c +++ b/src/drivers/disk.c @@ -9,12 +9,10 @@ #define SECTOR_SIZE 512 #define BLOCK_SIZE_IN_SECTORS 16 #define BLOCK_SIZE (SECTOR_SIZE * BLOCK_SIZE_IN_SECTORS) -#define BUFFER_SEG 0x7000 -#define BUFFER_OFF 0 -#define BUFFER_ADDR ((uint8_t *)((BUFFER_SEG << 4) + BUFFER_OFF)) #define CACHE_INVALID (~((uint64_t)0)) +static uint8_t *cache = NULL; static uint64_t cached_block = CACHE_INVALID; static struct { @@ -23,13 +21,18 @@ static struct { uint16_t offset; uint16_t segment; uint64_t lba; -} dap = { 16, BLOCK_SIZE_IN_SECTORS, BUFFER_OFF, BUFFER_SEG, 0 }; +} dap = { 16, BLOCK_SIZE_IN_SECTORS, 0, 0, 0 }; static int cache_block(int drive, uint64_t block) { if (block == cached_block) return 0; - dap.lba = block * BLOCK_SIZE_IN_SECTORS; + if (!cache) + cache = balloc(BLOCK_SIZE); + + dap.segment = rm_seg(cache); + dap.offset = rm_off(cache); + dap.lba = block * BLOCK_SIZE_IN_SECTORS; struct rm_regs r = {0}; r.eax = 0x4200; @@ -64,7 +67,7 @@ int read(int drive, void *buffer, uint64_t loc, uint64_t count) { if (chunk > BLOCK_SIZE - offset) chunk = BLOCK_SIZE - offset; - memcpy(buffer + progress, &BUFFER_ADDR[offset], chunk); + memcpy(buffer + progress, &cache[offset], chunk); progress += chunk; } diff --git a/src/fs/echfs.c b/src/fs/echfs.c index 6f8698c0..7b36ec4d 100644 --- a/src/fs/echfs.c +++ b/src/fs/echfs.c @@ -16,8 +16,6 @@ struct echfs_identity_table { #define END_OF_CHAIN (~((uint64_t)0)) #define FILE_TYPE 0 -#define CACHE_ADDR ((uint8_t *)(0x30000)) - static int cache_block(struct echfs_file_handle *file, uint64_t block) { // Load the file. uint64_t block_val = file->dir_entry.payload; @@ -33,7 +31,7 @@ sizeof(uint64_t)); if (block_val == END_OF_CHAIN) return -1; - return read_partition(file->disk, &file->mbr_part, CACHE_ADDR, block_val * file->block_size, file->block_size); + return read_partition(file->disk, &file->mbr_part, file->cache, block_val * file->block_size, file->block_size); } int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t count) { @@ -50,7 +48,7 @@ int echfs_read(struct echfs_file_handle *file, void *buf, uint64_t loc, uint64_t if (chunk > file->block_size - offset) chunk = file->block_size - offset; - memcpy(buf + progress, &CACHE_ADDR[offset], chunk); + memcpy(buf + progress, &file->cache[offset], chunk); progress += chunk; } @@ -76,6 +74,7 @@ int echfs_open(struct echfs_file_handle *ret, int disk, int partition, const cha ret->alloc_table_size = DIV_ROUNDUP(ret->block_count * sizeof(uint64_t), ret->block_size) * ret->block_size; ret->alloc_table_offset = 16 * ret->block_size; ret->dir_offset = ret->alloc_table_offset + ret->alloc_table_size; + ret->cache = balloc(ret->block_size); // Find the file in the root dir. for (uint64_t i = 0; i < ret->dir_length; i += sizeof(struct echfs_dir_entry)) { diff --git a/src/fs/echfs.h b/src/fs/echfs.h index 369212de..c03e02b7 100644 --- a/src/fs/echfs.h +++ b/src/fs/echfs.h @@ -27,6 +27,7 @@ struct echfs_file_handle { uint64_t alloc_table_size; uint64_t alloc_table_offset; uint64_t dir_offset; + uint8_t *cache; struct echfs_dir_entry dir_entry; }; diff --git a/src/lib/blib.c b/src/lib/blib.c index 55496d6f..26191d0b 100644 --- a/src/lib/blib.c +++ b/src/lib/blib.c @@ -8,6 +8,25 @@ #include #include +static size_t bump_allocator_base = 0x20000; + +void *balloc(size_t count) { + void *ret = (void *)bump_allocator_base; + bump_allocator_base += count; + return ret; +} + +// Only power of 2 alignments +void *balloc_aligned(size_t count, size_t alignment) { + if (bump_allocator_base & (alignment - 1)) { + bump_allocator_base &= ~(alignment - 1); + bump_allocator_base += alignment; + } + void *ret = (void *)bump_allocator_base; + bump_allocator_base += count; + return ret; +} + void pit_sleep(uint64_t pit_ticks) { uint64_t target = global_pit_tick + pit_ticks; while (global_pit_tick < target) { diff --git a/src/lib/blib.h b/src/lib/blib.h index 24c3ffdd..20083b73 100644 --- a/src/lib/blib.h +++ b/src/lib/blib.h @@ -7,6 +7,9 @@ void pit_sleep(uint64_t pit_ticks); int pit_sleep_and_quit_on_keypress(uint64_t pit_ticks); +void *balloc(size_t count); +void *balloc_aligned(size_t count, size_t alignment); + #define GETCHAR_CURSOR_LEFT (-10) #define GETCHAR_CURSOR_RIGHT (-11) #define GETCHAR_CURSOR_UP (-12) diff --git a/src/main.c b/src/main.c index 3b22f19a..4070e140 100644 --- a/src/main.c +++ b/src/main.c @@ -38,6 +38,8 @@ void main(int boot_drive) { print("qLoader 2\n\n"); print("=> Boot drive: %x\n", boot_drive); + void *config_addr = balloc(4096); + // Enumerate partitions. struct mbr_part parts[4]; for (int i = 0; i < 4; i++) { @@ -49,7 +51,7 @@ void main(int boot_drive) { print(" Found!\n"); if (!config_loaded) { if (!echfs_open(&f, boot_drive, i, CONFIG_NAME)) { - echfs_read(&f, (void *)0x100000, 0, f.dir_entry.size); + echfs_read(&f, config_addr, 0, f.dir_entry.size); config_loaded = 1; print(" Config file found and loaded!\n"); } @@ -62,22 +64,22 @@ void main(int boot_drive) { if (config_loaded) { char buf[32]; - if (!config_get_value(buf, 32, (void*)0x100000, "KERNEL_DRIVE")) { + if (!config_get_value(buf, 32, config_addr, "KERNEL_DRIVE")) { print("KERNEL_DRIVE not specified, using boot drive (%x)", boot_drive); drive = boot_drive; } else { drive = (int)strtoui(buf); } - if (!config_get_value(buf, 64, (void*)0x100000, "TIMEOUT")) { + if (!config_get_value(buf, 64, config_addr, "TIMEOUT")) { timeout = 5; } else { timeout = (int)strtoui(buf); } - config_get_value(buf, 32, (void*)0x100000, "KERNEL_PARTITION"); + config_get_value(buf, 32, config_addr, "KERNEL_PARTITION"); part = (int)strtoui(buf); - config_get_value(path, 128, (void*)0x100000, "KERNEL_PATH"); - config_get_value(cmdline, 128, (void*)0x100000, "KERNEL_CMDLINE"); - config_get_value(proto, 64, (void*)0x100000, "KERNEL_PROTO"); + config_get_value(path, 128, config_addr, "KERNEL_PATH"); + config_get_value(cmdline, 128, config_addr, "KERNEL_CMDLINE"); + config_get_value(proto, 64, config_addr, "KERNEL_PROTO"); } else { print(" !! NO CONFIG FILE FOUND ON BOOT DRIVE !!"); for (;;); diff --git a/src/protos/stivale.c b/src/protos/stivale.c index 2d902234..3c8dd7e1 100644 --- a/src/protos/stivale.c +++ b/src/protos/stivale.c @@ -79,7 +79,7 @@ void stivale_load(struct echfs_file_handle *fd) { &stivale_struct.framebuffer_bpp); } - volatile struct { + struct pagemap { uint64_t pml4[512]; uint64_t pml3_lo[512]; uint64_t pml3_hi[512]; @@ -87,7 +87,8 @@ void stivale_load(struct echfs_file_handle *fd) { uint64_t pml2_1gb[512]; uint64_t pml2_2gb[512]; uint64_t pml2_3gb[512]; - } *pagemap = (void *)0x20000; + }; + struct pagemap *pagemap = balloc_aligned(sizeof(struct pagemap), 0x1000); // first, zero out the pagemap for (uint64_t *p = (uint64_t *)pagemap; p < &pagemap->pml3_hi[512]; p++)