summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/boot/limine/memorymap.c2
-rw-r--r--arch/x86_64/elf.c27
-rw-r--r--arch/x86_64/init.c63
-rw-r--r--arch/x86_64/lib/object.c59
-rw-r--r--arch/x86_64/memory/koentry-ptr.c16
-rw-r--r--arch/x86_64/memory/message.c40
-rw-r--r--arch/x86_64/memory/page-mapping.c34
-rw-r--r--arch/x86_64/memory/pml4.c (renamed from arch/x86_64/memory/page_directory.c)86
-rw-r--r--arch/x86_64/memory/untyped_retype_page.c38
-rw-r--r--arch/x86_64/syscall/invoke-mapping.c8
-rw-r--r--arch/x86_64/syscall/wrappers.h2
-rw-r--r--arch/x86_64/usermode.c137
-rw-r--r--include/arch/x86_64/page-mapping.h12
-rw-r--r--include/arch/x86_64/page.h13
-rw-r--r--include/elf.h110
-rw-r--r--include/init.h19
-rw-r--r--include/jove.h3
-rw-r--r--include/memory.h8
-rw-r--r--include/object.h19
-rw-r--r--lib/untyped-retype.c38
-rw-r--r--lib/untyped.c16
-rw-r--r--main.c3
-rw-r--r--syscall/invoke-untyped.c5
23 files changed, 450 insertions, 308 deletions
diff --git a/arch/x86_64/boot/limine/memorymap.c b/arch/x86_64/boot/limine/memorymap.c
index ec0f545..43aecf7 100644
--- a/arch/x86_64/boot/limine/memorymap.c
+++ b/arch/x86_64/boot/limine/memorymap.c
@@ -31,7 +31,7 @@ boot_populate_untyped(void)
if(entry->type != LIMINE_MEMMAP_USABLE) continue;
size_t table_index = s_untyped_dir.self.data++;
- uintmax_t *untyped_data = vmem_phys_tovirt(entry->base);
+ uintmax_t *untyped_data = pptr_tovirt_ident(entry->base);
objdir_entry_t *table_entry = &s_untyped_dir.entries[table_index];
table_entry->type = KO_MEMORY_UNTYPED;
diff --git a/arch/x86_64/elf.c b/arch/x86_64/elf.c
new file mode 100644
index 0000000..696b7a7
--- /dev/null
+++ b/arch/x86_64/elf.c
@@ -0,0 +1,27 @@
+#include "elf.h"
+#include <stddef.h>
+
+int
+elf64_ehdr_valid(Elf64_Ehdr *ehdr)
+{
+ if(ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
+ ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
+ ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
+ ehdr->e_ident[EI_MAG3] != ELFMAG3)
+ return 0;
+ if(ehdr->e_ident[EI_CLASS] != ELFCLASS64) return 0;
+ if(ehdr->e_ident[EI_DATA] != ELFDATA2LSB) return 0;
+ if(ehdr->e_type != ET_EXEC) return 0;
+ if(ehdr->e_machine != EM_X86_64) return 0;
+
+ return 1;
+}
+
+void*
+elf64_loadexec(Elf64_Ehdr *ehdr)
+{
+ if(!elf64_ehdr_valid(ehdr)) return NULL;
+
+ void *entry = (void*)ehdr->e_entry;
+ return entry;
+}
diff --git a/arch/x86_64/init.c b/arch/x86_64/init.c
new file mode 100644
index 0000000..4ec7718
--- /dev/null
+++ b/arch/x86_64/init.c
@@ -0,0 +1,63 @@
+#include "init.h"
+#include "arch/x86_64/page.h"
+#include "device/processor.h"
+
+uintptr_t
+init_alloc_pageframe()
+{
+ objdir_entry_t *untyped_dir_entry = &_initDirectory.entries[INIT_OBJECT_UNTYPED_DIR];
+ objdir_t *untyped_dir = ko_entry_data(untyped_dir_entry);
+
+ /*Seek to the last member of untyped directory.*/
+ uint8_t lastmembi = 1;
+ for(; untyped_dir->entries[lastmembi].type == KO_MEMORY_UNTYPED; lastmembi++);
+ objdir_entry_t *lastmemb = &untyped_dir->entries[lastmembi];
+
+ objdir_entry_t pageframe;
+ ko_untyped_split(lastmemb, &pageframe, 0x1000);
+ return pageframe.data;
+}
+
+void
+init_map_pageframe(uintptr_t pptr, uintptr_t vptr, uint8_t pflags)
+{
+ uint64_t pathval;
+ uint16_t *path = (uint16_t*)&pathval;
+ pml4_get_path(vptr, 4, path);
+
+ processor_t *proc = processor_current();
+ pmle_t *pml4 = pptr_tovirt_ident(proc->pdir);
+
+ pmle_t *pmld = pml4;
+ for(uint8_t d = 0; d < 3; d++) {
+ uint16_t pmli = path[d];
+ pmle_t *pmle = &pmld[pmli];
+ if(!pmle->p) {
+ pmle->value = init_alloc_pageframe() | PAGE_PRESENT | PAGE_RW | PAGE_US;
+ }
+ pmld = pptr_tovirt_ident(pmle->paddr << 12);
+ }
+ pmld[path[3]].value = pptr | pflags;
+ __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
+}
+
+void
+init_ensure_page(uintptr_t vptr, uint8_t pflags)
+{
+ uint64_t pathval;
+ uint16_t *path = (uint16_t*)&pathval;
+ pml4_get_path(vptr, 4, path);
+
+ processor_t *proc = processor_current();
+ pmle_t *pml4 = pptr_tovirt_ident(proc->pdir);
+
+ pmle_t *pmld = pml4, *pmle;
+ for(uint8_t d = 0; d < 4; d++) {
+ uint16_t pmli = path[d];
+ pmle = &pmld[pmli];
+ if(!pmle->p) {
+ pmle->value = init_alloc_pageframe() | (d == 3 ? pflags : PAGE_PRESENT | PAGE_RW | PAGE_US);
+ }
+ pmld = pptr_tovirt_ident(pmle->paddr << 12);
+ }
+}
diff --git a/arch/x86_64/lib/object.c b/arch/x86_64/lib/object.c
new file mode 100644
index 0000000..4ab8f06
--- /dev/null
+++ b/arch/x86_64/lib/object.c
@@ -0,0 +1,59 @@
+#include "object.h"
+#include "error.h"
+#include "device/processor.h"
+#include "arch/x86_64/page.h"
+#include "arch/x86_64/page-mapping.h"
+
+void*
+ko_entry_data(objdir_entry_t *entry)
+{
+ if((intmax_t)entry->data < 0) return (void*)entry->data;
+ return pptr_tovirt_ident(entry->data);
+}
+
+uintptr_t
+ko_data_toentry(uintptr_t vptr)
+{
+ return vptr_tophys((void*)vptr);
+}
+
+int
+ko_message_unmap(objdir_entry_t *message, uintptr_t *saveptr)
+{
+ /* message data should point to the virtual address. */
+ /* If it doesn't, fail*/
+ if(!(message->extra & KODE_EX_MESSAGE_MAPPED)) return KE_BADCALL;
+ uintptr_t vptr = message->data;
+
+ processor_t *cproc = processor_current();
+ pmle_t *pml4 = pptr_tovirt_ident(cproc->pdir);
+
+ pmle_t *message_pmle = pml4_get_mapping(pml4, 4, vptr);
+ *saveptr = (uintptr_t)pptr_tovirt_ident(message_pmle->paddr << 12);
+
+ message_pmle->p = 0;
+ __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
+
+ message->extra &= ~KODE_EX_MESSAGE_MAPPED;
+ return 0;
+}
+
+int
+ko_message_remap(objdir_entry_t *message)
+{
+ if(message->extra & KODE_EX_MESSAGE_MAPPED) return KE_BADCALL;
+ uintptr_t vptr = message->data;
+
+ processor_t *cproc = processor_current();
+ pmle_t *pml4 = pptr_tovirt_ident(cproc->pdir);
+
+ pmle_t *message_pmle = pml4_get_mapping(pml4, 4, vptr);
+
+ message_pmle->p = 1;
+ __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
+
+ message->extra |= KODE_EX_MESSAGE_MAPPED;
+ return 0;
+}
+
+void ko_message_move(objdir_entry_t *message, uintptr_t vptr);
diff --git a/arch/x86_64/memory/koentry-ptr.c b/arch/x86_64/memory/koentry-ptr.c
deleted file mode 100644
index b32d4e7..0000000
--- a/arch/x86_64/memory/koentry-ptr.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "memory.h"
-#include "arch/x86_64/page.h"
-#include <stdint.h>
-
-void*
-ko_entry_data(objdir_entry_t *entry)
-{
- if((intmax_t)entry->data < 0) return (void*)entry->data;
- return vmem_phys_tovirt(entry->data);
-}
-
-uintptr_t
-ko_data_toentry(uintptr_t vptr)
-{
- return vmem_ident_tophys((void*)vptr);
-}
diff --git a/arch/x86_64/memory/message.c b/arch/x86_64/memory/message.c
index 1fbdfc8..d5bedb7 100644
--- a/arch/x86_64/memory/message.c
+++ b/arch/x86_64/memory/message.c
@@ -6,43 +6,3 @@
#include "arch/x86_64/page-mapping.h"
#include "print.h"
-int
-ko_message_unmap(objdir_entry_t *message, uintptr_t *saveptr)
-{
- /* message data should point to the virtual address. */
- /* If it doesn't, fail*/
- if(!(message->extra & KODE_EX_MESSAGE_MAPPED)) return KE_BADCALL;
- uintptr_t vptr = message->data;
-
- processor_t *cproc = processor_current();
- pmle_t *pml4 = vmem_phys_tovirt(cproc->pdir);
-
- pmle_t *message_pmle = mem_mapping_vptr_mapping(pml4, 4, vptr);
- *saveptr = (uintptr_t)vmem_phys_tovirt(message_pmle->paddr << 12);
-
- message_pmle->p = 0;
- __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
-
- message->extra &= ~KODE_EX_MESSAGE_MAPPED;
- return 0;
-}
-
-int
-ko_message_remap(objdir_entry_t *message)
-{
- if(message->extra & KODE_EX_MESSAGE_MAPPED) return KE_BADCALL;
- uintptr_t vptr = message->data;
-
- processor_t *cproc = processor_current();
- pmle_t *pml4 = vmem_phys_tovirt(cproc->pdir);
-
- pmle_t *message_pmle = mem_mapping_vptr_mapping(pml4, 4, vptr);
-
- message_pmle->p = 1;
- __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory");
-
- message->extra |= KODE_EX_MESSAGE_MAPPED;
- return 0;
-}
-
-void ko_message_move(objdir_entry_t *message, uintptr_t vptr);
diff --git a/arch/x86_64/memory/page-mapping.c b/arch/x86_64/memory/page-mapping.c
index d4b4e98..bbf210a 100644
--- a/arch/x86_64/memory/page-mapping.c
+++ b/arch/x86_64/memory/page-mapping.c
@@ -1,28 +1,28 @@
#include "arch/x86_64/page-mapping.h"
#include "arch/x86_64/page.h"
+#include "memory.h"
+#include "error.h"
#include <stddef.h>
#include "print.h"
-pmle_t*
-page_mapping_traverse(pmle_t *pml4, uint8_t depth, uint16_t *path)
+void
+mapping_setup_init()
{
- uint16_t pathi = path[0];
-
- pmle_t *pmle = &pml4[pathi];
- pmle_t *pmle_table = vmem_phys_tovirt(pmle->paddr << 12);
- if(depth == 0) return pmle;
- if(!pmle->p) return NULL;
- return page_mapping_traverse(pmle_table, depth - 1, path + 1);
+ pml4_setup_init();
}
-pmle_t*
-mem_mapping_vptr_mapping(pmle_t *pml4, uint8_t depth, uintptr_t vptr)
+void
+mapping_setup(objdir_entry_t *mapping)
{
- uint64_t pathval = 0;
- uint16_t *path = (uint16_t*)&pathval;
+ pmle_t *pml4 = (pmle_t*)ko_entry_data(mapping);
+ pml4_setup(pml4);
+}
- for(uint8_t i = 0; i < depth; i++) {
- path[i] = PML_I_FOR_LAYER(vptr, 4 - i);
- }
- return page_mapping_traverse(pml4, depth - 1, path);
+int
+mapping_try_map_obj(objdir_entry_t *mapping, uintptr_t vptr, objdir_entry_t *obj)
+{
+ if(vptr & 0xFFFF800000000000) return KE_OOB;
+ pmle_t *pml4 = (pmle_t*)ko_entry_data(mapping);
+ uintptr_t pptr = (uintptr_t)ko_entry_data(obj);
+ return pml4_try_map(pml4, pptr, vptr);
}
diff --git a/arch/x86_64/memory/page_directory.c b/arch/x86_64/memory/pml4.c
index 11e4861..fcfc897 100644
--- a/arch/x86_64/memory/page_directory.c
+++ b/arch/x86_64/memory/pml4.c
@@ -5,37 +5,78 @@
#include "object.h"
#include "string.h"
#include "jove.h"
+#include "error.h"
#include <stdint.h>
+#define IDENTITY_BASE 0xFFFF800000000000
+uintptr_t vptr_tophys(void *vptr)
+{
+ return ((uintptr_t)vptr) - IDENTITY_BASE;
+}
+
physptr_t
-vmem_tophys_koff(virtptr_t v)
+vptr_tophys_koff(virtptr_t v)
{
return v - (physptr_t)&_kernel_start + _boot_kernel_phys_base;
}
-#define IDENTITY_BASE 0xFFFF800000000000
void*
-vmem_phys_tovirt(physptr_t p)
+pptr_tovirt_ident(physptr_t p)
{
return (void*)(p + IDENTITY_BASE);
}
-uintptr_t vmem_ident_tophys(void *vptr)
-{
- return ((uintptr_t)vptr) - IDENTITY_BASE;
-}
-
void*
pmle_get_page(pmle_t entry)
{
uintptr_t pptr = entry.paddr << 12;
- return vmem_phys_tovirt(pptr);
+ return pptr_tovirt_ident(pptr);
+}
+
+void
+pml4_get_path(uintptr_t vptr, uint8_t depth, uint16_t *path)
+{
+ for(uint8_t i = 0; i < depth; i++) {
+ path[i] = PML_I_FOR_LAYER(vptr, 4 - i);
+ }
}
-uint8_t
-pmle_level(pmle_t entry)
+pmle_t*
+pml4_traverse(pmle_t *pml4, uint8_t depth, uint16_t *path)
{
- return entry.osflg;
+ uint16_t pathi = path[0];
+
+ pmle_t *pmle = &pml4[pathi];
+ pmle_t *pmle_table = pptr_tovirt_ident(pmle->paddr << 12);
+ if(depth == 0) return pmle;
+ if(!pmle->p) return NULL;
+ return pml4_traverse(pmle_table, depth - 1, path + 1);
+}
+
+pmle_t*
+pml4_get_mapping(pmle_t *pml4, uint8_t depth, uintptr_t vptr)
+{
+ uint64_t pathval = 0;
+ uint16_t *path = (uint16_t*)&pathval;
+
+ pml4_get_path(vptr, depth, path);
+ return pml4_traverse(pml4, depth - 1, path);
+}
+
+int
+pml4_try_map(pmle_t *pml4, uintptr_t pptr, uintptr_t vptr)
+{
+ uint64_t pathval = 0;
+ uint16_t *path = (uint16_t*)&pathval;
+
+ pml4_get_path(vptr, 4, path);
+ pmle_t *mapping = pml4_traverse(pml4, 3, path);
+
+ if(mapping == NULL) return KE_DNE;
+ if(mapping->p) return KE_FULL;
+
+ mapping->value = pptr | PAGE_PRESENT | PAGE_RW | PAGE_US;
+ return KE_OK;
}
__attribute__((aligned(0x1000))) pmle_t s_kernel_pml4[512]; // Page L4
@@ -47,7 +88,7 @@ __attribute__((aligned(0x1000))) pmle_t s_idmap_pml3[512];
__attribute__((aligned(0x1000))) pmle_t s_idmap_pml2[512];
void
-vmem_setup(void)
+pml4_setup_init(void)
{
memset(s_kernel_pml4, 0, 0x1000);
memset(s_kernel_pml3, 0, 0x1000);
@@ -63,13 +104,13 @@ vmem_setup(void)
size_t kernel_size = kernel_end - kernel_start;
size_t kernel_size_pages = (kernel_size / 0x1000) + 1;
- physptr_t kernel_pml4_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml4);
- physptr_t kernel_pml3_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml3);
- physptr_t kernel_pml2_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml2);
- physptr_t kernel_pml1_base = vmem_tophys_koff((virtptr_t)&s_kernel_pml1);
+ physptr_t kernel_pml4_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml4);
+ physptr_t kernel_pml3_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml3);
+ physptr_t kernel_pml2_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml2);
+ physptr_t kernel_pml1_base = vptr_tophys_koff((virtptr_t)&s_kernel_pml1);
- physptr_t idmap_pml3_base = vmem_tophys_koff((virtptr_t)&s_idmap_pml3);
- physptr_t idmap_pml2_base = vmem_tophys_koff((virtptr_t)&s_idmap_pml2);
+ physptr_t idmap_pml3_base = vptr_tophys_koff((virtptr_t)&s_idmap_pml3);
+ physptr_t idmap_pml2_base = vptr_tophys_koff((virtptr_t)&s_idmap_pml2);
processor_t *processor = processor_current();
processor->pdir = kernel_pml4_base;
@@ -103,3 +144,10 @@ vmem_setup(void)
.data = kernel_pml4_base
};
}
+
+void
+pml4_setup(pmle_t *pml4)
+{
+ memset(pml4, 0, 0x800);
+ memcpy(&pml4[256], &s_kernel_pml4[256], 0x800);
+}
diff --git a/arch/x86_64/memory/untyped_retype_page.c b/arch/x86_64/memory/untyped_retype_page.c
deleted file mode 100644
index 32afe2c..0000000
--- a/arch/x86_64/memory/untyped_retype_page.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "memory.h"
-#include "arch/x86_64/page.h"
-#include "print.h"
-#include <stddef.h>
-
-static int
-s_untyped_retype(
- objdir_entry_t *untyped_entry,
- size_t size,
- size_t align,
- void **dest)
-{
- if(untyped_entry->type != KO_MEMORY_UNTYPED) return -1;
- if((untyped_entry->data & (align - 1)) != 0) return -2; //EALIGN
-
- uintptr_t *untyped_data = vmem_phys_tovirt(untyped_entry->data);
- uintmax_t untyped_size = *untyped_data;
-
- if(untyped_size <= size) {
- return -3;
- }
-
- *untyped_data -= size;
- *dest = (void*)(untyped_entry->data + untyped_size - size);
-
- return 0;
-}
-
-int untyped_retype_page(objdir_entry_t *untyped_entry, void **dest)
-{
- int r = s_untyped_retype(untyped_entry, 0x1000, 0x1000, dest);
- if(r != 0) return r;
-
- #ifdef DBG_MEM
- klogf("Untyped block %p retyped to page at %p\n", untyped_entry->data, *dest);
- #endif
- return r;
-}
diff --git a/arch/x86_64/syscall/invoke-mapping.c b/arch/x86_64/syscall/invoke-mapping.c
index be401d6..5fde8be 100644
--- a/arch/x86_64/syscall/invoke-mapping.c
+++ b/arch/x86_64/syscall/invoke-mapping.c
@@ -16,7 +16,7 @@ s_handle_invoke_mapping_exists(
size_t payload_at
)
{
- pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data);
+ pmle_t *pml4 = (pmle_t*)pptr_tovirt_ident(target_entry->data);
pmle_t *target_pml;
uint8_t target_depth;
SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml);
@@ -36,7 +36,7 @@ s_handle_invoke_mapping_map(
size_t payload_at
)
{
- pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data);
+ pmle_t *pml4 = (pmle_t*)pptr_tovirt_ident(target_entry->data);
pmle_t *target_pml;
uint8_t target_depth;
SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml);
@@ -85,7 +85,7 @@ s_handle_invoke_mapping_unmap(
size_t payload_at
)
{
- pmle_t *pml4 = (pmle_t*)vmem_phys_tovirt(target_entry->data);
+ pmle_t *pml4 = (pmle_t*)pptr_tovirt_ident(target_entry->data);
pmle_t *target_pml;
uint8_t target_depth;
SYSCALL_PAYLOAD_TAKEPML(payload, payload_at, pml4, target_depth, target_pml);
@@ -105,7 +105,7 @@ s_handle_invoke_mapping_unmap(
if(dest_entry->type != KO_NONE) return KE_FULL;
uintptr_t pmle_addr = target_pml->paddr << 12;
- size_t *untyped = vmem_phys_tovirt(pmle_addr);
+ size_t *untyped = pptr_tovirt_ident(pmle_addr);
__asm__ volatile("invlpg (%0)":: "r"(untyped): "memory");
*untyped = 0x1000;
diff --git a/arch/x86_64/syscall/wrappers.h b/arch/x86_64/syscall/wrappers.h
index a6fdf88..0803262 100644
--- a/arch/x86_64/syscall/wrappers.h
+++ b/arch/x86_64/syscall/wrappers.h
@@ -8,7 +8,7 @@
SYSCALL_PAYLOAD_TAKEL(payload, at, depth, uint8_t); \
if(((depth + 1) * sizeof(uint16_t)) + at >= KO_MESSAGE_BYTES) return KE_BADMSG; \
if(depth == 0 && *(uint16_t*)&payload[at] > 255) return KE_OOB; \
- pml = page_mapping_traverse(pml4, depth, (uint16_t*)&payload[at]); \
+ pml = pml4_traverse(pml4, depth, (uint16_t*)&payload[at]); \
at += (depth + 1) * sizeof(uint16_t)
#endif
diff --git a/arch/x86_64/usermode.c b/arch/x86_64/usermode.c
index aa626a9..8975993 100644
--- a/arch/x86_64/usermode.c
+++ b/arch/x86_64/usermode.c
@@ -1,76 +1,4 @@
-#include "arch/x86_64/object.h"
-#include "object.h"
-#include "bootargs.h"
-#include "device/initrd.h"
-#include "object.h"
-#include "panic.h"
-#include "string.h"
-#include "device/processor.h"
-#include "arch/x86_64/page.h"
-#include "print.h"
-static tcb_t s_init_tcb;
-
-//Dynamic allocation hell!!!
-static uintptr_t
-s_new_mapping(objdir_t *untyped_dir)
-{
- objdir_entry_t *untyped_entry = NULL;
- for(int i = untyped_dir->self.data - 1; i != 0; i--) {
- untyped_entry = &untyped_dir->entries[i];
- if(untyped_entry->type != KO_MEMORY_UNTYPED) continue;
- uintptr_t mapping = 0;
- int err = untyped_retype_page(untyped_entry, (void**)&mapping);
- if(err != 0) continue;
- return mapping;
- }
- kpanic("Could not allocate page for init\n");
-}
-
-static pmle_t*
-s_ensure_mapping_layer(pmle_t *pml, objdir_t *untyped_dir, uintptr_t addr, uint8_t layer)
-{
- pmli_t pmli = PML_I_FOR_LAYER(addr, layer);
- if(pml[pmli].p)
- return pmle_get_page(pml[pmli]);
-
- uintptr_t table_phys = s_new_mapping(untyped_dir);
- pmle_t *table = vmem_phys_tovirt(table_phys);
- memset(table, 0, 0x1000);
-
- pml[pmli] = (pmle_t) {
- .p = 1,
- .rw = 1,
- .us = 1,
- .osflg = (layer - 1) & 3,
- .paddr = table_phys >> 12
- };
- __asm__ volatile("invlpg (%0)":: "r"(table_phys));
- return vmem_phys_tovirt(table_phys);
-}
-
-static uintptr_t
-s_map_page(pmle_t *pml4, objdir_t *untyped_dir, uintptr_t addr)
-{
- pmle_t *pml3 = s_ensure_mapping_layer(pml4, untyped_dir, addr, 4);
- pmle_t *pml2 = s_ensure_mapping_layer(pml3, untyped_dir, addr, 3);
- pmle_t *pml1 = s_ensure_mapping_layer(pml2, untyped_dir, addr, 2);
-
- pmli_t pml1i = PML_I_FOR_LAYER(addr, 1);
- pmle_t *pmle = &pml1[pml1i];
-
- uintptr_t pptr = s_new_mapping(untyped_dir);
-
- *pmle = (pmle_t) {
- .p = 1,
- .rw = 1,
- .us = 1,
- .osflg = 0,
- .paddr = pptr >> 12
- };
- __asm__ volatile("invlpg (%0)":: "r"(addr));
- return pptr;
-}
__attribute__((noreturn))
static void
@@ -85,68 +13,3 @@ s_enter_usermode(void *ip, void *sp)
"r"(sp), "r"(ip): "memory");
for(;;);
}
-
-void
-init_load(void)
-{
- const char *init_filename = bootargs_getarg("init");
- if(init_filename == NULL) {
- kpanic("Missing boot argument \"init\"");
- }
- tar_header_t *init_header = initrd_find_file(init_filename);
- if(init_header == NULL) {
- kpanic("Init file not found in initrd. (expected \"%s\")", init_filename);
- }
-
- _initDirectory.entries[INIT_OBJECT_TCB] = (objdir_entry_t) {
- .type = KO_TCB,
- .data = vmem_tophys_koff((uintptr_t)&s_init_tcb)
- };
-
- objdir_t *untyped_dir = (objdir_t*)_initDirectory.entries[INIT_OBJECT_UNTYPED_DIR].data;
- pmle_t *pml4 = vmem_phys_tovirt(_initDirectory.entries[INIT_OBJECT_PAGEMAP].data & ~3ULL);
-
- //Reserve and map pages for init binary
- size_t init_size = initrd_file_size(init_header);
-
- size_t init_pages = (init_size >> 12);
- uintptr_t init_base = 0x1000;
-
- for(size_t i = 0; i < init_pages + 1; i++) {
- s_map_page(pml4, untyped_dir, init_base + (i * 0x1000));
- }
- //Copy over init data
- memcpy((void*)init_base, (&((tar_block_t*)init_header)[1])->data, init_size);
-
- //Create a user stack
- uintptr_t stack_base = 0x00007FFFFFFFF000;
- s_map_page(pml4, untyped_dir, stack_base);
- uintptr_t sp = stack_base + 0xFF0;
-
- //Create a kernel stack for the init TCB
- uintptr_t ksp_base = (uintptr_t)&s_init_tcb.kstack;
- s_init_tcb.ksp = ksp_base + 0xFF0;
-
- processor_t *proc = (processor_t*)processor_current();
- proc->tss.rsp0 = s_init_tcb.ksp;
- klogf("RSP0 %p\n", s_init_tcb.ksp);
-
- //Create a message object for init
- uintptr_t message_base = init_base + (init_pages << 12);
- message_base += ((~(message_base & 0xFFF)) & 0xFFF) + 1;
-
- uintptr_t message_phys = s_map_page(pml4, untyped_dir, message_base);
- _initDirectory.entries[INIT_OBJECT_MESSAGE] = (objdir_entry_t) {
- .type = KO_MESSAGE,
- .extra = KODE_EX_MESSAGE_MAPPED,
- .data = message_base
- };
-
- //Write message address to user stack.
- sp -= sizeof(uintptr_t);
- *((uintptr_t*)sp) = message_base;
-
- //Setup usermode and jump
- proc->tcb = &s_init_tcb;
- s_enter_usermode((void*)init_base, (void*)sp);
-}
diff --git a/include/arch/x86_64/page-mapping.h b/include/arch/x86_64/page-mapping.h
index fd620ea..8389132 100644
--- a/include/arch/x86_64/page-mapping.h
+++ b/include/arch/x86_64/page-mapping.h
@@ -3,13 +3,19 @@
#include "arch/x86_64/page.h"
-pmle_t *page_mapping_traverse(pmle_t *pml4, uint8_t depth, uint16_t *path);
+pmle_t *pml4_traverse(pmle_t *pml4, uint8_t depth, uint16_t *path);
/**@FUNC Get the pmle associated with this virtual address down to a given depth.
* At depth=0, gets &pml4[pml4i]
* At depth=1, gets &pml4[pml4i][pml3i]
* At depth=2, gets &pml4[pml4i][pml3i][pml2i]
- * etc...*/
-pmle_t *mem_mapping_vptr_mapping(pmle_t *pml4, uint8_t depth, uintptr_t vptr);
+ * etc...
+ * @PARAM pml4 table to get mapping from.
+ * @PARAM depth how deep to traverse for the mapping.
+ * @PARAM vptr address to get mapping for.
+ * @RETURN pointer to pmle (if exists)*/
+pmle_t *pml4_get_mapping(pmle_t *pml4, uint8_t depth, uintptr_t vptr);
+
+int pml4_try_map(pmle_t *pml4, uintptr_t pptr, uintptr_t vptr);
#endif
diff --git a/include/arch/x86_64/page.h b/include/arch/x86_64/page.h
index 7c6186a..910b898 100644
--- a/include/arch/x86_64/page.h
+++ b/include/arch/x86_64/page.h
@@ -36,13 +36,16 @@ typedef uint16_t pmli_t;
#define PML_SHL(l) (((l) * 9) + 3)
#define PML_I_FOR_LAYER(v, l) (((v) >> PML_SHL(l)) % 512)
-uintptr_t vmem_ident_tophys(void *vptr);
-void *vmem_phys_tovirt(uintptr_t pptr);
-uintptr_t vmem_tophys_koff(uintptr_t v);
+uintptr_t vptr_tophys(void *vptr);
+uintptr_t vptr_tophys_koff(uintptr_t v);
+
+void *pptr_tovirt_ident(uintptr_t pptr);
void *pmle_get_page(pmle_t entry);
-uint8_t pmle_level(pmle_t entry);
-int untyped_retype_page(objdir_entry_t *untyped_entry, void **dest_ptr);
+void pml4_setup_init(void);
+void pml4_setup(pmle_t *pml4);
+
+void pml4_get_path(uintptr_t vptr, uint8_t depth, uint16_t *path);
#endif
diff --git a/include/elf.h b/include/elf.h
new file mode 100644
index 0000000..05e3e83
--- /dev/null
+++ b/include/elf.h
@@ -0,0 +1,110 @@
+#ifndef _JOVE_ELF_H
+#define _JOVE_ELF_H 1
+
+#include <stdint.h>
+
+/*A subset of the SystemV ELF ABI that only loads statically linked binaries.*/
+
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Word;
+typedef uint32_t Elf32_Addr;
+typedef uint32_t Elf32_Off;
+
+typedef Elf32_Half Elf64_Half;
+typedef Elf32_Word Elf64_Word;
+typedef uint64_t Elf64_Xword;
+typedef uintptr_t Elf64_Addr;
+typedef uint64_t Elf64_Off;
+
+enum {
+ EI_MAG0 = 0,
+ EI_MAG1,
+ EI_MAG2,
+ EI_MAG3,
+ EI_CLASS,
+ EI_DATA,
+ EI_VERSION,
+ EI_OSABI,
+ EI_ABIVERSION,
+ EI_PAD
+};
+#define EI_NIDENT 16
+
+#define ELFMAG0 0x7f
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+
+#define ELFCLASSNONE 0
+#define ELFCLASS64 2
+
+#define ELFDATANONE 0
+#define ELFDATA2LSB 1
+
+#define ET_NONE 0
+#define ET_EXEC 2
+
+#define EM_X86_64 62
+
+#define EV_NONE 0
+#define EV_CURRENT 1
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT];
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_NOBITS 8
+
+#define SHF_WRITE 0x1
+#define SHF_ALLOC 0x2
+
+typedef struct {
+ Elf64_Word sh_name;
+ Elf64_Word sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Word sh_link;
+ Elf64_Word sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
+#define PT_NULL 0
+#define PT_LOAD 1
+
+#define PF_X 1
+#define PF_W 2
+#define PF_R 4
+
+typedef struct
+{
+ Elf64_Word p_type;
+ Elf64_Word p_flags;
+ Elf64_Off p_offset;
+ Elf64_Addr p_vaddr;
+ Elf64_Addr p_paddr;
+ Elf64_Xword p_filesz;
+ Elf64_Xword p_memsz;
+ Elf64_Xword p_align;
+} Elf64_Phdr;
+
+int elf64_ehdr_valid(Elf64_Ehdr *ehdr);
+
+#endif
diff --git a/include/init.h b/include/init.h
index aa722b1..2174785 100644
--- a/include/init.h
+++ b/include/init.h
@@ -1,9 +1,24 @@
#ifndef _JOVE_INIT_H
#define _JOVE_INIT_H 1
-#ifdef __x86_64__
+#include <stdint.h>
-#endif
+enum {
+ INIT_OBJECT_ROOTDIR = 0,
+ INIT_OBJECT_PAGEMAP,
+ INIT_OBJECT_PROCESSOR_DIR,
+ INIT_OBJECT_UNTYPED_DIR,
+ INIT_OBJECT_INITRD_DIR,
+ INIT_OBJECT_TCB,
+ INIT_OBJECT_MESSAGE,
+ INIT_OBJECT_LOG
+};
+
+#include "object.h"
+extern objdir_t _initDirectory;
+
+uintptr_t init_alloc_pageframe();
+void init_map_pageframe(uintptr_t pptr, uintptr_t vptr, uint8_t pflags);
void init_load(void);
diff --git a/include/jove.h b/include/jove.h
index 63d2ce9..fc4c91f 100644
--- a/include/jove.h
+++ b/include/jove.h
@@ -6,9 +6,6 @@
extern void (*_kernel_start)(void);
extern void (*_kernel_end)(void);
-#include "object.h"
-extern objdir_t _initDirectory;
-
NORETURN void hcf(void);
#endif
diff --git a/include/memory.h b/include/memory.h
index 2f75b60..901060c 100644
--- a/include/memory.h
+++ b/include/memory.h
@@ -9,11 +9,9 @@ typedef uintptr_t virtptr_t;
#define KERNEL_STACK_SIZE 0x1000
-void vmem_setup(void);
+void mapping_setup_init(void);
+void mapping_setup(objdir_entry_t *mapping);
-int untyped_retype_kernel_stack(objdir_entry_t *untyped_entry, objdir_entry_t *dest_entry);
-
-void *ko_entry_data(objdir_entry_t *entry);
-uintptr_t ko_data_toentry(uintptr_t vptr);
+int mapping_try_map_obj(objdir_entry_t *mapping, uintptr_t vptr, objdir_entry_t *obj);
#endif
diff --git a/include/object.h b/include/object.h
index c8621ee..4cf5159 100644
--- a/include/object.h
+++ b/include/object.h
@@ -2,17 +2,7 @@
#define _JOVE_OBJECT_H
#include <stdint.h>
-
-enum {
- INIT_OBJECT_ROOTDIR = 0,
- INIT_OBJECT_PAGEMAP,
- INIT_OBJECT_PROCESSOR_DIR,
- INIT_OBJECT_UNTYPED_DIR,
- INIT_OBJECT_INITRD_DIR,
- INIT_OBJECT_TCB,
- INIT_OBJECT_MESSAGE,
- INIT_OBJECT_LOG
-};
+#include <stddef.h>
enum
{
@@ -64,13 +54,18 @@ typedef struct jove_ObjectDirectory
objdir_entry_t *objdir_seek(objdir_t *dir, uint8_t *path, unsigned long pathw);
unsigned long objdir_pathw(objdir_t *dir, uint8_t *path);
+void *ko_entry_data(objdir_entry_t *entry);
+uintptr_t ko_data_toentry(uintptr_t vptr);
+
int ko_message_unmap(objdir_entry_t *message, uintptr_t *saveptr);
int ko_message_remap(objdir_entry_t *message);
void ko_message_move(objdir_entry_t *message, uintptr_t vptr);
+int ko_untyped_split(objdir_entry_t *untyped, objdir_entry_t *dest, size_t bytes);
+
int ko_untyped_retype_objdir(objdir_entry_t *target);
int ko_untyped_retype_memory_mapping(objdir_entry_t *target);
int ko_untyped_retype_tcb(objdir_entry_t *target);
-int ko_untyped_retype_message(objdir_entry_t *target);
+int ko_untyped_retype_message(objdir_entry_t *target, uintptr_t vptr);
#endif
diff --git a/lib/untyped-retype.c b/lib/untyped-retype.c
index 70fb4d2..526f19e 100644
--- a/lib/untyped-retype.c
+++ b/lib/untyped-retype.c
@@ -1,11 +1,43 @@
-#include <object.h>
-#include <memory.h>
+#include "object.h"
+#include "memory.h"
#include <stddef.h>
-#include <error.h>
+#include "error.h"
+#include "string.h"
int
ko_untyped_retype_objdir(objdir_entry_t *target)
{
size_t *untyped = ko_entry_data(target);
if(*untyped != 0x1000) return -KE_BADSIZE;
+
+ objdir_t *objdir = (objdir_t*)untyped;
+ memset(objdir, 0, 0x1000);
+
+ objdir->self = (objdir_entry_t) {
+ .type = KO_OBJECT_DIRECTORY,
+ .data = target->data
+ };
+ *target = (objdir_entry_t) {
+ .type = KO_OBJECT_DIRECTORY,
+ .lock = 0,
+ .extra = 0,
+ .data = objdir->self.data
+ };
+ return 0;
+}
+
+int
+ko_untyped_retype_message(objdir_entry_t *target, uintptr_t vptr)
+{
+ size_t *untyped = ko_entry_data(target);
+ if(*untyped != 0x1000) return -KE_BADSIZE;
+
+ memset(untyped, 0, KO_MESSAGE_BYTES);
+ *target = (objdir_entry_t) {
+ .type = KO_OBJECT_DIRECTORY,
+ .lock = 0,
+ .extra = 0,
+ .data = target->data
+ };
+ return 0;
}
diff --git a/lib/untyped.c b/lib/untyped.c
new file mode 100644
index 0000000..8a20f63
--- /dev/null
+++ b/lib/untyped.c
@@ -0,0 +1,16 @@
+#include "include/object.h"
+#include "error.h"
+
+int
+ko_untyped_split(objdir_entry_t *target, objdir_entry_t *dest, size_t bytes)
+{
+ size_t *untyped = ko_entry_data(target);
+ if(*untyped <= bytes) return KE_TOOSMALL;
+
+ *untyped -= bytes;
+ dest->data = target->data + *untyped;
+ *(size_t*)ko_entry_data(dest) = bytes;
+ dest->type = KO_MEMORY_UNTYPED;
+
+ return 0;
+}
diff --git a/main.c b/main.c
index 82cbbea..579f68c 100644
--- a/main.c
+++ b/main.c
@@ -27,12 +27,11 @@ _jove_main(void)
bsp_setup();
boot_populate_untyped();
- vmem_setup();
+ mapping_setup_init();
#ifdef ENABLE_INITRD
initrd_setup();
#endif
- init_load();
kprintf("Reached end of kernel main!\n");
hcf();
}
diff --git a/syscall/invoke-untyped.c b/syscall/invoke-untyped.c
index a89306e..483d36f 100644
--- a/syscall/invoke-untyped.c
+++ b/syscall/invoke-untyped.c
@@ -95,6 +95,11 @@ s_handle_invoke_untyped_retype(
switch(retype) {
case KO_OBJECT_DIRECTORY:
return ko_untyped_retype_objdir(target);
+ case KO_MESSAGE: {
+ uintptr_t vptr;
+ SYSCALL_PAYLOAD_TAKEL(payload, payload_at, vptr, uintptr_t);
+ return ko_untyped_retype_message(target, vptr);
+ }
default: return KE_BADTYPE;
}
}