summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--stage2/paging.asm2
-rw-r--r--stage3/heap.c28
-rw-r--r--stage3/heap.h3
-rw-r--r--stage3/main.c68
-rw-r--r--stage3/paging.asm343
-rw-r--r--stage3/paging.h19
7 files changed, 36 insertions, 428 deletions
diff --git a/Makefile b/Makefile
index eea6f87..646f781 100644
--- a/Makefile
+++ b/Makefile
@@ -47,7 +47,6 @@ STAGE3_C = \
STAGE3 = $(STAGE3_C) \
stage3/isr.o \
stage3/yield.o \
- stage3/paging.o \
stage3/watchdog.o
PAD_BOUNDARY = pad() { truncate -s $$(echo "($$(du -b $$1 | cut -f1)+$$2-1)/$$2*$$2" | bc) $$1; }; pad
diff --git a/stage2/paging.asm b/stage2/paging.asm
index cd6ea1c..4e5e2f1 100644
--- a/stage2/paging.asm
+++ b/stage2/paging.asm
@@ -24,7 +24,7 @@ paging:
mov [di], eax
add di, 8
add eax, 0x1000
- cmp eax, 0x200000
+ cmp eax, 0x400000
jb .build_pt
; enable paging and long mode
diff --git a/stage3/heap.c b/stage3/heap.c
index 85bb8e9..2c54d8c 100644
--- a/stage3/heap.c
+++ b/stage3/heap.c
@@ -129,34 +129,6 @@ void heap_add(void *ptr, usize size)
kfree(h + 1);
}
-void heap_add_region(MemRegion *region)
-{
- switch (region->used) {
- // region is reserved
- case -1:
- break;
-
- // region is entirely free
- case 0:
- heap_add(region->start, region->size);
- break;
-
- // region is partly used
- default: {
- void *region_end = region->start + region->size;
-
- // rounds up region->start to pagesize align
- void *use_begin = (void *) ((u64) (region->start + PAGESIZE - 1) & ~(PAGESIZE - 1));
- void *use_end = use_begin + region->used;
-
- heap_add(region->start, use_begin - region->start);
- heap_add(use_end, region_end - use_end);
- }
- }
-
- region->used = -1; // just to be safe
-}
-
heap_header *heap_get_free_ptr()
{
return free_ptr;
diff --git a/stage3/heap.h b/stage3/heap.h
index 10fe261..0b7057b 100644
--- a/stage3/heap.h
+++ b/stage3/heap.h
@@ -2,12 +2,9 @@
#define HEAP_H
#include "def.h"
-#include "paging.h"
void heap_init();
-
void heap_add(void *ptr, usize size);
-void heap_add_region(MemRegion *region);
void *try_kmalloc(usize size);
void *kmalloc(usize siz);
diff --git a/stage3/main.c b/stage3/main.c
index 5f6756f..e9b5717 100644
--- a/stage3/main.c
+++ b/stage3/main.c
@@ -1,5 +1,4 @@
#include "def.h"
-#include "paging.h"
#include "gfx.h"
#include "halt.h"
#include "heap.h"
@@ -18,6 +17,17 @@
#include "rng.h"
#include "debug.h"
+typedef enum {
+ MEM_USABLE = 1,
+ MEM_RESERVED = 2,
+} mem_region_type;
+
+typedef struct __attribute__((packed)) {
+ void *start;
+ usize size;
+ usize type;
+} mem_region;
+
char keymap[256] = { '\0' };
void keyboard_handler()
@@ -60,43 +70,35 @@ void keyboard_handler()
void kmain()
{
- heap_init();
+ // PML3
+ for (u64 page = 0; page < 512*512; page++)
+ ((u64 *) 0x200000)[page] = (page << 30) | 0b10000011; // bit 7 is for huge pages
+
+ // PML4
+ for (u64 tbl = 0; tbl < 512; tbl++)
+ ((u64 *) 0x1000)[tbl] = (0x200000 + tbl * 0x1000) | 0b11;
-#define MMAP for (MemRegion *mreg = (void *) 0x500; mreg->start != nil; mreg++)
+#define MMAP for (mem_region *mreg = (void *) 0x500; mreg->start != nil; mreg++)
+
+ // heap init
+ heap_init();
MMAP {
- // remove anything between 0x100000 and 0x200000. it has already been mapped
+ // remove anything between 0x100000 and 0x400000. it is used for kernel and page tables
usize start = (usize) mreg->start;
- if (start >= 0x100000 && start < 0x200000) {
- if (start + mreg->size <= 0x200000) {
+ if (start >= 0x100000 && start < 0x400000) {
+ if (start + mreg->size <= 0x400000) {
mreg->size = 0; // kill it
} else {
- mreg->size = start + mreg->size - 0x200000;
- mreg->start = (void *) 0x200000;
+ mreg->size = start + mreg->size - 0x400000;
+ mreg->start = (void *) 0x400000;
}
}
- }
- // backup memory map
- usize n_mreg = 0;
- MMAP n_mreg++;
- MemRegion mregs[n_mreg];
- {
- usize i = 0;
- MMAP mregs[i++] = *mreg;
+ // add to heap
+ if (mreg->type == MEM_USABLE) // usable
+ heap_add(mreg->start, mreg->size);
}
- // setup paging
- MMAP page_region(mreg);
-
- page_region(&(MemRegion) {
- .start = (void *) (u64) gfx_info->framebuffer,
- .size = gfx_info->pitch * gfx_info->height,
- .used = MEM_RESERVED,
- });
-
- // heap init
- MMAP heap_add_region(mreg);
-
// font init
font_init();
font_set_size(1);
@@ -106,13 +108,13 @@ void kmain()
print(S("welcome to cuddles\n"));
// memory map
- print(S("memory map:\n"));
- for (usize i = 0; i < n_mreg; i++) {
- print_num_pad((u64) mregs[i].start, 16, 16, ' ');
+ print(S("heap memory:\n"));
+ MMAP {
+ print_num_pad((u64) mreg->start, 16, 16, ' ');
print(S(" | "));
- print_num_pad((u64) mregs[i].start + mregs[i].size, 16, 16, ' ');
+ print_num_pad((u64) mreg->start + mreg->size, 16, 16, ' ');
print(S(" | "));
- print_dec(mregs[i].used);
+ print_dec(mreg->type);
print(S("\n"));
}
diff --git a/stage3/paging.asm b/stage3/paging.asm
deleted file mode 100644
index f58bb98..0000000
--- a/stage3/paging.asm
+++ /dev/null
@@ -1,343 +0,0 @@
-global page_region
-%define PAGEBUFSIZE 0x10 * 0x1000
-
-section .bss
-
-ALIGN(4096)
-pagebuf_data: resb PAGEBUFSIZE
-
-section .data
-
-pagebuf_init:
- .start: dq pagebuf_data
- .size: dq PAGEBUFSIZE
- .used: dq 0
-
-pagebuf: dq pagebuf_init
-
-next_page: dq 0
-
-section .text
-
-; allocate new page table buffer
-alloc:
- ; rsi = buffer (result)
- ; rdi = next_page
- ; r8 = pagebuf
- ; rbx = upper
- ; rax = tmp; used_next
-
- mov r8, [pagebuf] ; *pagebuf
- mov rsi, [r8] ; start = pagebuf->start
-
- mov rbx, [r8+8] ; size = pagebuf->size
- add rbx, rsi ; upper_have = start + size
-
- ; round *up* to 0x1000 align
- mov rax, 0xfff
- add rsi, rax
- not rax
- and rsi, rax ; aligned_start = (start + 0xfff) & (~0xfff)
-
- mov rax, [r8+16] ; used = pagebuf->used
- add rax, 0x1000
- add rsi, rax ; upper_need = aligned_start + used + 0x1000
-
- cmp rsi, rbx ; if upper_need > upper_have
- ja .newbuf ; current region is full, get new
-
- cmp rsi, r10 ; if upper_need >= next_page
- jae .oom ; out of memory (target buffer isn't paged yet)
-
- mov [r8+16], rax ; pagebuf->used = used + 0x1000
-
- ; clear out buffer
-
- mov rbx, rsi
- sub rsi, 0x1000
-
-.clear:
- sub rbx, 8
- mov qword[rbx], 0
- cmp rbx, rsi
- jne .clear
-
- ret
-
-; select next page buffer
-.newbuf:
- cmp r8, pagebuf_init
- jne .nextbuf
-
- mov r8, 0x500
- jmp .trybuf
-
-.nextbuf:
- add r8, 24
-
-.trybuf:
- cmp qword[r8], 0
- je .oom ; last region reached
-
- mov rax, [r8+16]
-
- cmp rax, -1
- je .nextbuf ; region is reserved
-
- cmp rax, 0
- jne .oom ; region has not been paged yet
-
- mov [pagebuf], r8
- jmp alloc
-
-.oom:
- push rdi
-
- mov rdi, .oom_msg
- ; call print_str
-
- pop rdi
-
- ; call print_hex
- ; call newline
-
- jmp $
-
-.oom_msg: db "out of memory for page table", 10, "next_page = ", 0
-
-; get/create page tables
-get_tables:
-; level 4
-
- ; rdi = address (arg, persist)
- ; rax = tmp
- ; rbx = mask
- ; rcx = bits (persist)
- ; rdx = level (persist)
- ; r8 = table address
- ; rsi = next offset (persist)
-
- mov cl, 12+9*4
- mov dl, 4
-
- mov rsi, 0x1000
-
-; level 4
-.level:
- dec dl
- mov r8, rdi
- mov rbx, -1 ; reset remainder mask
- shl rbx, cl ; update remainder mask
- not rbx ; negate remainder mask
- and r8, rbx ; apply remainder mask
-
- mov al, 9
- mul dl
- add al, 12
- mov cl, al
-
- shr r8, cl ; divide
- shl r8, 3 ; multiply by 8
-
- mov rbx, 0xfff ; 0x1000 alignment
- not rbx ; offset mask
-
- and rsi, rbx ; apply offset mask
- add r8, rsi ; add offset
- push r8 ; store
-
- cmp dl, 0
- je .done
-
- mov rsi, [r8] ; next offset
- cmp rsi, 0
- jne .level
-
- call alloc
- or rsi, 3
- mov r8, [rsp]
- mov [r8], rsi
-
- jmp .level
-
-.done:
- pop r11
- pop r12
- pop r13
- pop r14
-
- ret
-
-space:
- mov dil, ' '
- ; jmp print_chr
-
-page_region:
- push rbx
- push r12
- push r13
- push r14
- push r15
-
- mov r9, rdi
-
- mov rdi, [r9] ; ptr = mmap_entry->ptr
- mov r10, [next_page]
-
- push rdi
-
- mov rax, 1 << 63
-
- or rdi, rax
- ; call print_hex
- ; call space
-
- mov rdi, [r9+8]
- add rdi, [rsp]
- or rdi, rax
-
- ; call print_hex
- ; call newline
-
- pop rdi
-
- ; for usable region (type = 1), set mmap_entry->used = 0
- ; for reserved region (type = 2), set mmap_entry->used = -1
- xor rax, rax
- xor rbx, rbx
- mov eax, dword[r9+16]
- cmp rax, 1
- je .set_used
- dec rbx
-.set_used:
- mov [r9+16], rbx
-
- mov r10, rdi
- mov r15, rdi ; r15 = end of region
- add r15, [r9+8]
-
- mov rax, 0xfff
- not rax
- and rdi, rax ; round down to 0x1000 aligned
-
- cmp rdi, r10
- jb .get_tables
-
- mov r10, rdi
-
-.get_tables:
- call get_tables ; page tables into r11-r14
-
- ; start filling L1 map
-.l1:
- mov rax, rdi
- or rax, 3
- mov [r11], rax
-
- add rdi, 0x1000
-
- cmp rdi, r10
- jb .next
-
- mov r10, rdi
-
-.next:
- cmp rdi, r15 ; if next >= end
- jae .done
-
- ; prepare rcx mask for later
- mov rcx, -1
- shl rcx, 3
-
- ; bump L1
-
- add r11, 8
- mov rax, r11
- and rax, 0xfff
- jnz .l1
-
- ; bump L2
-
- add r12, 8
- mov rax, r12
- and rax, 0xfff
- jnz .l2
-
- ; bump L3
-
- add r13, 8
- mov rax, r13
- and rax, 0xfff
- jnz .l3
-
- ; bump L4
-
- add r14, 8
- mov rax, r14
- and rax, 0xfff
- jnz .l4
-
- ; machine has more than 256TB of RAM, tell user to fuck off
- jmp .bruh
-
-.l4:
- mov r13, [r14]
- and r13, rcx
- jnz .l3
-
- call alloc
- mov r13, rsi
- or rsi, 3
- mov [r14], rsi
-
-.l3:
- mov r12, [r13]
- and r12, rcx
- jnz .l2
-
- call alloc
- mov r12, rsi
- or rsi, 3
- mov [r13], rsi
-
-.l2:
- mov r11, [r12]
- and r11, rcx
- jnz .l2
-
- call alloc
- mov r11, rsi
- or rsi, 3
- mov [r12], rsi
-
- jmp .l1
-
-.done:
- mov [next_page], r10
-
- pop r15
- pop r14
- pop r13
- pop r12
- pop rbx
-
- ret
-
-.bruh:
- mov rdi, .bruh_msg
- ; call print_str
- jmp $
-
-.bruh_msg: db "bruh why do you have more than 256TB of RAM (you fucking glow)", 10, 0
-
-; identity map available memory
-old_page_map:
- mov r9, 0x0500 ; mmap_entry
-.entry:
- cmp qword[r9], 0
- je .done
- call page_region
- add r9, 24
- jmp .entry
-.done:
- ret
diff --git a/stage3/paging.h b/stage3/paging.h
deleted file mode 100644
index 319b297..0000000
--- a/stage3/paging.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef PAGING_H
-#define PAGING_H
-
-#include "def.h"
-
-typedef enum {
- MEM_USABLE = 1,
- MEM_RESERVED = 2,
-} MemRegionType;
-
-typedef struct __attribute__((packed)) {
- void *start;
- usize size;
- usize used;
-} MemRegion;
-
-void page_region(MemRegion *region);
-
-#endif