summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/boot/limine/framebuffer.c18
-rw-r--r--arch/x86_64/hal/obj.h2
-rw-r--r--arch/x86_64/hal/paging.c34
-rw-r--r--arch/x86_64/hal/paging.h2
-rw-r--r--arch/x86_64/hal/process.c2
-rw-r--r--arch/x86_64/main.c2
-rw-r--r--arch/x86_64/sys/init.c53
7 files changed, 94 insertions, 19 deletions
diff --git a/arch/x86_64/boot/limine/framebuffer.c b/arch/x86_64/boot/limine/framebuffer.c
index aa93496..ea7c714 100644
--- a/arch/x86_64/boot/limine/framebuffer.c
+++ b/arch/x86_64/boot/limine/framebuffer.c
@@ -2,6 +2,7 @@
#include "jove.h"
#include "config.h"
#include "hal/framebuffer.h"
+#include "lib/string.h"
#include "lib/printf.h"
/*We don't know the size of the framebuffer until runtime, but at the same
@@ -14,6 +15,7 @@
#define FRAMEBUFFER_MAX_GIANTPAGES ((FRAMEBUFFER_MAX_HUGEPAGES + 511) / 512)
PAGEALIGN static page_t fb_pml2[FRAMEBUFFER_MAX_GIANTPAGES][512];
+PAGEALIGN static page_t fb_pml1[FRAMEBUFFER_MAX_HUGEPAGES][512];
extern page_t _kernel_pml3[512];
@@ -21,6 +23,9 @@ void*
fb_remap(uintptr_t fb_address,
size_t fb_bytes)
{
+ memset(fb_pml2, 0, 0x1000 * FRAMEBUFFER_MAX_GIANTPAGES);
+ memset(fb_pml1, 0, 0x1000 * FRAMEBUFFER_MAX_HUGEPAGES);
+
fb_address &= ~IDENT_VIRT_BASE;
size_t fb_pages = (fb_bytes + 4095) >> 12;
size_t fb_hugepages = (fb_pages + 511) >> 9;
@@ -32,15 +37,22 @@ fb_remap(uintptr_t fb_address,
}
for(size_t pml2 = 0; pml2 < fb_giantpages; pml2++) {
- uintptr_t fb_pml2_pptr = KPTR_TOPHYS((uintptr_t)fb_pml2[pml2]);
+ uintptr_t fb_pml2_pptr = KPTR_TOPHYS(&fb_pml2[pml2]);
_kernel_pml3[pml2].value = fb_pml2_pptr | PAGE_PRESENT | PAGE_GLOBAL | PAGE_WRITEABLE;
}
for(size_t pml1 = 0; pml1 < fb_hugepages; pml1++) {
size_t pml2 = pml1 >> 9;
size_t pml1_mod = pml1 % 512;
- uintptr_t fb_off = fb_address + (pml1 << 21);
- fb_pml2[pml2][pml1_mod].value = fb_off | PAGE_PRESENT | PAGE_GLOBAL | PAGE_WRITEABLE | PAGE_PS;
+ uintptr_t pml1_pptr = KPTR_TOPHYS(&fb_pml1[pml1]);
+ fb_pml2[pml2][pml1_mod].value = pml1_pptr | PAGE_PRESENT | PAGE_GLOBAL | PAGE_WRITEABLE;
+ }
+
+ for(size_t pml0 = 0; pml0 < fb_pages; pml0++) {
+ size_t pml1 = pml0 >> 9;
+ size_t pml0_mod = pml0 % 512;
+ uintptr_t pml0_pptr = fb_address + (pml0 << 12);
+ fb_pml1[pml1][pml0_mod].value = pml0_pptr | PAGE_PRESENT | PAGE_GLOBAL | PAGE_WRITEABLE;
}
uintptr_t fb_virt = IDENT_VIRT_BASE | (511ULL << PMLI_SHL(3));
diff --git a/arch/x86_64/hal/obj.h b/arch/x86_64/hal/obj.h
index 645727d..9569a8a 100644
--- a/arch/x86_64/hal/obj.h
+++ b/arch/x86_64/hal/obj.h
@@ -8,8 +8,6 @@
enum
{
JOVE_OBJ_SERIAL_COM = 0x81,
- JOVE_OBJ_PAGE_FRAME,
- JOVE_OBJ_PAGE_MAPPING,
};
/*Represents a locked kernel object pointer inside of a object directory.*/
diff --git a/arch/x86_64/hal/paging.c b/arch/x86_64/hal/paging.c
index c1a22a2..9ef67ab 100644
--- a/arch/x86_64/hal/paging.c
+++ b/arch/x86_64/hal/paging.c
@@ -1,8 +1,10 @@
#include "paging.h"
#include "arch/x86_64/x86_64.h"
#include "jove.h"
+#include "init.h"
#include "config.h"
#include "smp.h"
+#include "hal/obj.h"
#include "lib/string.h"
#include "lib/printf.h"
#include "lib/panic.h"
@@ -13,11 +15,11 @@ PAGEALIGN page_t _kernel_pml3[512];
PAGEALIGN page_t _kernel_pml2[512];
PAGEALIGN page_t _kernel_pml1[512];
-#define IDENT_HUGEPAGES ((PHYS_BIGPAGES_MAX + 511) / 512)
-#define IDENT_GIANTPAGES ((IDENT_HUGEPAGES + 511) / 512)
+#define IDENT_GIANTPAGES ((PHYS_HUGEPAGES_MAX + 511) / 512)
+#define IDENT_MASSIVEPAGES ((IDENT_GIANTPAGES + 511) / 512)
-PAGEALIGN static page_t ident_pml3[IDENT_GIANTPAGES][512];
-PAGEALIGN static page_t ident_pml2[IDENT_HUGEPAGES][512];
+PAGEALIGN static page_t ident_pml3[IDENT_MASSIVEPAGES][512];
+PAGEALIGN static page_t ident_pml2[IDENT_GIANTPAGES][512];
void*
phys_tovirt(uintptr_t phys)
@@ -80,6 +82,9 @@ paging_pml4_init(void)
memset(_kernel_pml2, 0, 0x1000);
memset(_kernel_pml1, 0, 0x1000);
+ memset(ident_pml3, 0, 0x1000 * IDENT_MASSIVEPAGES);
+ memset(ident_pml2, 0, 0x1000 * IDENT_GIANTPAGES);
+
/*Paging entries depend on physical addresses to properly map.
* Since the virtual kernel address differs from the physical memory address,
* we need to convert the pointers using the physical memory pointer passed
@@ -140,24 +145,22 @@ paging_pml4_init(void)
/*Identity pages are mapped as huge pages starting at the 256'th PML3 entry.
*We want to support any range of physical memory up to several TiB, so
*the mapper has to consider multiple heirarchies of huge pages.*/
- for(size_t l3 = 0; l3 < IDENT_GIANTPAGES; l3++) {
- memset(ident_pml3[l3], 0, 0x1000);
- uintptr_t ident_pml3_pptr = KPTR_TOPHYS((uintptr_t)ident_pml3[l3]);
+
+ for(size_t l3 = 0; l3 < IDENT_MASSIVEPAGES; l3++) {
+ uintptr_t ident_pml3_pptr = KPTR_TOPHYS(&ident_pml3[l3]);
_kernel_pml4[256 + l3].value = ident_pml3_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_GLOBAL;
}
- for(size_t l2 = 0; l2 < IDENT_HUGEPAGES; l2++) {
+ for(size_t l2 = 0; l2 < IDENT_GIANTPAGES; l2++) {
size_t l3 = l2 / 512;
size_t l2_mod = l2 % 512;
- memset(ident_pml2[l2], 0, 0x1000);
- uintptr_t ident_pml2_pptr = KPTR_TOPHYS((uintptr_t)ident_pml2[l2]);
-
+ uintptr_t ident_pml2_pptr = KPTR_TOPHYS(&ident_pml2[l2]);
ident_pml3[l3][l2_mod].value = ident_pml2_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_GLOBAL;
}
- for(size_t l1 = 0; l1 < PHYS_BIGPAGES_MAX; l1++) {
+ for(size_t l1 = 0; l1 < PHYS_HUGEPAGES_MAX; l1++) {
size_t l2 = l1 / 512;
size_t l1_mod = l1 % 512;
@@ -167,6 +170,13 @@ paging_pml4_init(void)
paging_pml4_switch(kernel_pml4_pptr);
+ {
+ jove_owned_obj_t *pgdir_o = obj_take(objdir_getlocal(_rootdir_obj, ROOTDIR_PAGEDIR_I));
+ obj_settype(pgdir_o, JOVE_OBJ_PAGEDIR);
+ obj_setvalue(pgdir_o, kernel_pml4_pptr);
+ obj_release(pgdir_o);
+ }
+
/*Before tasking, if the kernel has a bug and crashes we need some
* information about what happened.*/
extern struct int_stackframe *(*__int_handles[])(struct int_stackframe*);
diff --git a/arch/x86_64/hal/paging.h b/arch/x86_64/hal/paging.h
index 54df1eb..eb916a3 100644
--- a/arch/x86_64/hal/paging.h
+++ b/arch/x86_64/hal/paging.h
@@ -44,7 +44,7 @@ extern void *_kernel_physptr;
#define IDENT_VIRT_BASE 0xFFFF800000000000ULL
#define KERNEL_VIRT_BASE 0xFFFFFFFF80000000ULL
-#define KPTR_TOPHYS(v) (v - KERNEL_VIRT_BASE + (uintptr_t)_kernel_physptr)
+#define KPTR_TOPHYS(v) ((uintptr_t)v - KERNEL_VIRT_BASE + (uintptr_t)_kernel_physptr)
uintptr_t paging_get_pml4(void);
void paging_pml4_init(void);
diff --git a/arch/x86_64/hal/process.c b/arch/x86_64/hal/process.c
index dd49456..fb295c0 100644
--- a/arch/x86_64/hal/process.c
+++ b/arch/x86_64/hal/process.c
@@ -12,7 +12,7 @@ static pcb_t *s_init_pcb = (pcb_t*)&s_init_pcb_bytes;
void
processing_setup(void (*process_main))
{
- uintptr_t ksp = (uintptr_t)&s_init_pcb_bytes + 8;
+ uintptr_t ksp = ((uintptr_t)&s_init_pcb_bytes) + 0xFF0;
s_init_pcb->ksp = (void*)ksp;
s_init_pcb->pml4 = paging_get_pml4();
diff --git a/arch/x86_64/main.c b/arch/x86_64/main.c
index 44591a5..2d4599e 100644
--- a/arch/x86_64/main.c
+++ b/arch/x86_64/main.c
@@ -1,4 +1,5 @@
#include "jove.h"
+#include "init.h"
#include "lib/printf.h"
#include "lib/virtterm.h"
#include "lib/panic.h"
@@ -44,5 +45,6 @@ kernel_entry(void)
static void
kernel_process_entry(void)
{
+ init_setup();
kpanic("Reached the end of kernel main!\n");
}
diff --git a/arch/x86_64/sys/init.c b/arch/x86_64/sys/init.c
new file mode 100644
index 0000000..06fbe48
--- /dev/null
+++ b/arch/x86_64/sys/init.c
@@ -0,0 +1,53 @@
+#include "init.h"
+#include "config.h"
+#include "jove.h"
+#include "hal/obj.h"
+#include "lib/string.h"
+#include "lib/panic.h"
+#include "arch/x86_64/hal/paging.h"
+#include "boot/cmdline.h"
+#include "boot/initrd.h"
+
+#define INIT_PROGRAM_HUGEPAGES_MAX ((INIT_PROGRAM_PAGES_MAX + 511) / 512)
+#define INIT_STACK_HUGEPAGES_MAX ((INIT_STACK_PAGES_MAX + 511) / 512)
+
+PAGEALIGN static page_t s_init_program_pml3[512];
+PAGEALIGN static page_t s_init_program_pml2[512];
+PAGEALIGN static page_t s_init_program_pml1[INIT_PROGRAM_HUGEPAGES_MAX][512];
+
+PAGEALIGN static page_t s_init_stack_pml3[512];
+PAGEALIGN static page_t s_init_stack_pml2[512];
+PAGEALIGN static page_t s_init_stack_pml1[INIT_STACK_HUGEPAGES_MAX][512];
+
+void
+init_setup(void)
+{
+ memset(s_init_program_pml3, 0, 0x1000);
+ memset(s_init_program_pml2, 0, 0x1000);
+ memset(s_init_program_pml1, 0, 0x1000 * INIT_PROGRAM_HUGEPAGES_MAX);
+
+ memset(s_init_stack_pml3, 0, 0x1000);
+ memset(s_init_stack_pml2, 0, 0x1000);
+ memset(s_init_stack_pml1, 0, 0x1000 * INIT_STACK_HUGEPAGES_MAX);
+
+ uintptr_t init_program_pml3_pptr = KPTR_TOPHYS(s_init_program_pml3);
+ uintptr_t init_program_pml2_pptr = KPTR_TOPHYS(s_init_program_pml2);
+ uintptr_t init_program_pml1_pptr = KPTR_TOPHYS(s_init_program_pml1);
+
+ uintptr_t init_stack_pml3_pptr = KPTR_TOPHYS(s_init_stack_pml3);
+ uintptr_t init_stack_pml2_pptr = KPTR_TOPHYS(s_init_stack_pml2);
+ uintptr_t init_stack_pml1_pptr = KPTR_TOPHYS(s_init_stack_pml1);
+
+ //Get the init file data from the initrd.
+ const char *init_path = cmdline_getarg("init");
+ if(init_path == NULL) {
+ kpanic("Kernel commandline is missing 'init' arg.\n");
+ }
+
+ jove_owned_obj_t *initrd_obj = obj_take(objdir_getlocal(_rootdir_obj, ROOTDIR_INITRD_I));
+ jove_owned_obj_t *initfile_obj = initrd_seek(initrd_obj, init_path);
+ if(initfile_obj == NULL) {
+ kpanic("init: Cannot find file '%s' in initrd.\n", init_path);
+ }
+ obj_release(initrd_obj);
+}