file: Add ability to rename memory regions for memory loaded files so they do not have to be allocated twice for things such as compressed module loading
diff --git a/limine-pxe.bin b/limine-pxe.bin
index b5faf26f..024e20c7 100644
Binary files a/limine-pxe.bin and b/limine-pxe.bin differ
diff --git a/limine.bin b/limine.bin
index ce15104a..774e3217 100644
Binary files a/limine.bin and b/limine.bin differ
diff --git a/stage2.map b/stage2.map
index ec71a10c..c996646c 100644
Binary files a/stage2.map and b/stage2.map differ
diff --git a/stage2/fs/file.c b/stage2/fs/file.c
index 22c6fadb..6606e3cf 100644
--- a/stage2/fs/file.c
+++ b/stage2/fs/file.c
@@ -7,6 +7,7 @@
#include <lib/blib.h>
#include <mm/pmm.h>
#include <lib/part.h>
+#include <lib/libc.h>
bool fs_get_guid(struct guid *guid, struct part *part) {
if (echfs_check_signature(part)) {
@@ -29,7 +30,6 @@ int fopen(struct file_handle *ret, struct part *part, const char *filename) {
ret->fd = (void *)fd;
ret->read = (void *)echfs_read;
- ret->part = *part;
ret->size = fd->dir_entry.size;
return 0;
@@ -44,7 +44,6 @@ int fopen(struct file_handle *ret, struct part *part, const char *filename) {
ret->fd = (void *)fd;
ret->read = (void *)ext2_read;
- ret->part = *part;
ret->size = fd->size;
return 0;
@@ -60,7 +59,6 @@ int fopen(struct file_handle *ret, struct part *part, const char *filename) {
ret->fd = (void *)fd;
ret->read = (void *)fat32_read;
- ret->part = *part;
ret->size = fd->size_bytes;
return 0;
@@ -70,5 +68,23 @@ int fopen(struct file_handle *ret, struct part *part, const char *filename) {
}
int fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count) {
- return fd->read(fd->fd, buf, loc, count);
+ if (fd->is_memfile) {
+ memcpy(buf, fd->fd + loc, count);
+ return 0;
+ } else {
+ return fd->read(fd->fd, buf, loc, count);
+ }
+}
+
+void *freadall(struct file_handle *fd, uint32_t type) {
+ if (fd->is_memfile) {
+ memmap_alloc_range((uint64_t)(size_t)fd->fd, fd->size, type, false);
+ return fd->fd;
+ } else {
+ void *ret = ext_mem_alloc(fd->size);
+ if (fd->read(fd->fd, ret, 0, fd->size)) {
+ panic("freadall error");
+ }
+ return ret;
+ }
}
diff --git a/stage2/fs/file.h b/stage2/fs/file.h
index c91d906b..82a4c1ce 100644
--- a/stage2/fs/file.h
+++ b/stage2/fs/file.h
@@ -2,13 +2,14 @@
#define __FS__FILE_H__
#include <stdint.h>
+#include <stddef.h>
#include <stdbool.h>
#include <lib/part.h>
bool fs_get_guid(struct guid *guid, struct part *part);
struct file_handle {
- struct part part;
+ bool is_memfile;
void *fd;
int (*read)(void *fd, void *buf, uint64_t loc, uint64_t count);
uint64_t size;
@@ -16,5 +17,6 @@ struct file_handle {
int fopen(struct file_handle *ret, struct part *part, const char *filename);
int fread(struct file_handle *fd, void *buf, uint64_t loc, uint64_t count);
+void *freadall(struct file_handle *fd, uint32_t type);
#endif
diff --git a/stage2/lib/elf.c b/stage2/lib/elf.c
index 55042ceb..1c614521 100644
--- a/stage2/lib/elf.c
+++ b/stage2/lib/elf.c
@@ -309,7 +309,7 @@ int elf64_load(struct file_handle *fd, uint64_t *entry_point, uint64_t *top, uin
if (this_top > *top)
*top = this_top;
- memmap_alloc_range((size_t)load_vaddr, (size_t)phdr.p_memsz, alloc_type);
+ memmap_alloc_range((size_t)load_vaddr, (size_t)phdr.p_memsz, alloc_type, true);
fread(fd, (void *)(uint32_t)load_vaddr, phdr.p_offset, phdr.p_filesz);
@@ -362,7 +362,7 @@ int elf32_load(struct file_handle *fd, uint32_t *entry_point, uint32_t *top, uin
if (this_top > *top)
*top = this_top;
- memmap_alloc_range((size_t)phdr.p_paddr, (size_t)phdr.p_memsz, alloc_type);
+ memmap_alloc_range((size_t)phdr.p_paddr, (size_t)phdr.p_memsz, alloc_type, true);
fread(fd, (void *)phdr.p_paddr, phdr.p_offset, phdr.p_filesz);
diff --git a/stage2/lib/uri.c b/stage2/lib/uri.c
index f123253b..56f3167b 100644
--- a/stage2/lib/uri.c
+++ b/stage2/lib/uri.c
@@ -174,14 +174,11 @@ static bool uri_boot_dispatch(struct file_handle *fd, char *s_part, char *path)
return true;
}
-static int mem_read(void *fd, void *buf, uint64_t loc, uint64_t count) {
- memcpy(buf, fd + loc, count);
- return 0;
-}
-
bool uri_open(struct file_handle *fd, char *uri) {
bool ret;
+ memset(fd, 0, sizeof(struct file_handle));
+
char *resource, *root, *path;
uri_resolve(uri, &resource, &root, &path);
@@ -217,7 +214,7 @@ bool uri_open(struct file_handle *fd, char *uri) {
fread(fd, src, 0, fd->size);
if (tinf_gzip_uncompress(compressed_fd.fd, src, fd->size))
panic("tinf error");
- compressed_fd.read = mem_read;
+ compressed_fd.is_memfile = true;
*fd = compressed_fd;
}
diff --git a/stage2/mm/pmm.c b/stage2/mm/pmm.c
index f5815a14..14d86a80 100644
--- a/stage2/mm/pmm.c
+++ b/stage2/mm/pmm.c
@@ -237,7 +237,7 @@ void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type)
// We now reserve the range we need.
int64_t aligned_length = entry_top - alloc_base;
- memmap_alloc_range((uint64_t)alloc_base, (uint64_t)aligned_length, type);
+ memmap_alloc_range((uint64_t)alloc_base, (uint64_t)aligned_length, type, true);
void *ret = (void *)(size_t)alloc_base;
@@ -252,7 +252,7 @@ void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type)
panic("High memory allocator: Out of memory");
}
-void memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type) {
+void memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, bool free_only) {
uint64_t top = base + length;
if (base < 0x100000) {
@@ -262,7 +262,7 @@ void memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type) {
}
for (size_t i = 0; i < memmap_entries; i++) {
- if (memmap[i].type != 1)
+ if (free_only && memmap[i].type != 1)
continue;
uint64_t entry_base = memmap[i].base;
diff --git a/stage2/mm/pmm.h b/stage2/mm/pmm.h
index be014cf0..a843f599 100644
--- a/stage2/mm/pmm.h
+++ b/stage2/mm/pmm.h
@@ -2,6 +2,8 @@
#define __MM__PMM_H__
#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
#include <sys/e820.h>
#define MEMMAP_USABLE 1
@@ -18,7 +20,7 @@ extern size_t memmap_entries;
void init_memmap(void);
struct e820_entry_t *get_memmap(size_t *entries);
void print_memmap(struct e820_entry_t *mm, size_t size);
-void memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type);
+void memmap_alloc_range(uint64_t base, uint64_t length, uint32_t type, bool free_only);
void *ext_mem_alloc(size_t count);
void *ext_mem_alloc_type(size_t count, uint32_t type);
diff --git a/stage2/protos/linux.c b/stage2/protos/linux.c
index 8fc5ad69..32303302 100644
--- a/stage2/protos/linux.c
+++ b/stage2/protos/linux.c
@@ -132,7 +132,7 @@ void linux_load(char *config, char *cmdline) {
// load kernel
print("Loading kernel...\n");
- memmap_alloc_range(KERNEL_LOAD_ADDR, kernel->size - real_mode_code_size, 0);
+ memmap_alloc_range(KERNEL_LOAD_ADDR, kernel->size - real_mode_code_size, 0, true);
fread(kernel, (void *)KERNEL_LOAD_ADDR, real_mode_code_size, kernel->size - real_mode_code_size);
size_t modules_mem_base = INITRD_LOAD_ADDR;
@@ -147,7 +147,7 @@ void linux_load(char *config, char *cmdline) {
print("Loading module `%s`...\n", module_path);
- memmap_alloc_range(modules_mem_base, module.size, 0);
+ memmap_alloc_range(modules_mem_base, module.size, 0, true);
fread(&module, (void *)modules_mem_base, 0, module.size);
modules_mem_base += module.size;
diff --git a/stage2/protos/stivale.c b/stage2/protos/stivale.c
index ad826b46..26baef6d 100644
--- a/stage2/protos/stivale.c
+++ b/stage2/protos/stivale.c
@@ -134,25 +134,16 @@ void stivale_load(char *config, char *cmdline) {
memcpy(m->string, module_string, str_len);
}
+ print("stivale: Loading module `%s`...\n", module_path);
+
struct file_handle f;
if (!uri_open(&f, module_path))
panic("Requested module with path \"%s\" not found!", module_path);
- void *module_addr = (void *)(((uint32_t)top_used_addr & 0xfff) ?
- ((uint32_t)top_used_addr & ~((uint32_t)0xfff)) + 0x1000 :
- (uint32_t)top_used_addr);
-
- print("stivale: Loading module `%s`...\n", module_path);
-
- memmap_alloc_range((size_t)module_addr, f.size, 10);
- fread(&f, module_addr, 0, f.size);
-
- m->begin = (uint64_t)(size_t)module_addr;
+ m->begin = (uint64_t)(size_t)freadall(&f, STIVALE_MMAP_KERNEL_AND_MODULES);
m->end = m->begin + f.size;
m->next = 0;
- top_used_addr = (uint64_t)(size_t)m->end;
-
*prev_mod_ptr = (uint64_t)(size_t)m;
prev_mod_ptr = &m->next;
diff --git a/stage2/protos/stivale2.c b/stage2/protos/stivale2.c
index 9527564c..8532f23a 100644
--- a/stage2/protos/stivale2.c
+++ b/stage2/protos/stivale2.c
@@ -182,24 +182,15 @@ void stivale2_load(char *config, char *cmdline, bool pxe) {
memcpy(m->string, module_string, str_len);
}
+ print("stivale2: Loading module `%s`...\n", module_path);
+
struct file_handle f;
if (!uri_open(&f, module_path))
panic("Requested module with path \"%s\" not found!", module_path);
- void *module_addr = (void *)(((uint32_t)top_used_addr & 0xfff) ?
- ((uint32_t)top_used_addr & ~((uint32_t)0xfff)) + 0x1000 :
- (uint32_t)top_used_addr);
-
- print("stivale2: Loading module `%s`...\n", module_path);
-
- memmap_alloc_range((size_t)module_addr, f.size, 0x1001);
- fread(&f, module_addr, 0, f.size);
-
- m->begin = (uint64_t)(size_t)module_addr;
+ m->begin = (uint64_t)(size_t)freadall(&f, STIVALE2_MMAP_KERNEL_AND_MODULES);
m->end = m->begin + f.size;
- top_used_addr = (uint64_t)(size_t)m->end;
-
print("stivale2: Requested module %u:\n", i);
print(" Path: %s\n", module_path);
print(" String: %s\n", m->string);
