:: commit 79a9f31ceba26d954f3a48ee86d6f401e3fdce55

mintsuki <mintsuki@protonmail.com> — 2021-01-02 20:44

parents: 7a0777d7c1

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);
tab: 248 wrap: offon