summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Makefile1
-rw-r--r--kernel/include/debug.h6
-rw-r--r--kernel/include/heap.h14
-rw-r--r--kernel/include/kernel_vma.h6
-rw-r--r--kernel/include/paging.h1
-rw-r--r--kernel/src/boot/boot.S158
-rw-r--r--kernel/src/boot/boot64.S25
-rw-r--r--kernel/src/boot/multiboot2.c3
-rw-r--r--kernel/src/cpu/gdt.c6
-rw-r--r--kernel/src/devices/disc.c5
-rw-r--r--kernel/src/kernel.ld9
-rw-r--r--kernel/src/libk/stdio.c2
-rw-r--r--kernel/src/main.c6
-rw-r--r--kernel/src/mem/heap.c23
-rw-r--r--kernel/src/mem/paging.c55
-rw-r--r--kernel/src/mem/paging_asm.S4
-rw-r--r--kernel/src/misc/debug.c6
-rw-r--r--kernel/src/sys/userspace_asm.S2
18 files changed, 138 insertions, 194 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 9d7658b..981af74 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -25,7 +25,6 @@ OBJS = \
src/mem/heap.o \
src/mem/paging_asm.o \
src/mem/paging.o \
- src/misc/debug.o \
src/misc/graphics.o \
src/misc/stdbuff.o \
src/sys/syscall_asm.o \
diff --git a/kernel/include/debug.h b/kernel/include/debug.h
deleted file mode 100644
index 74648b9..0000000
--- a/kernel/include/debug.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef DEBUG_H
-#define DEBUG_H
-
-void bochs_breakpoint(void);
-
-#endif
diff --git a/kernel/include/heap.h b/kernel/include/heap.h
index b2d9a00..464a36a 100644
--- a/kernel/include/heap.h
+++ b/kernel/include/heap.h
@@ -2,11 +2,17 @@
#define HEAP_H
#include <types.h>
+#include <kernel_vma.h>
-#define HEAP_VMEM_ADDR 0xc2000000
-#define HEAP_PMEM_ADDR 0x02000000
-#define HEAP_SIZE 0x02000000
-#define HEAP_BLOCK_SIZE 0x00000010
+#define HEAP1_VMEM_ADDR KERNEL_VMA + 0x01000000
+#define HEAP1_PMEM_ADDR 0x01000000
+#define HEAP1_SIZE 0x01000000
+#define HEAP1_BLOCK_SIZE 0x00000010
+
+#define HEAP2_VMEM_ADDR KERNEL_VMA + 0x02000000
+#define HEAP2_PMEM_ADDR 0x02000000
+#define HEAP2_SIZE 0x01000000
+#define HEAP2_BLOCK_SIZE 0x00001000
struct kheapblock_t {
struct kheapblock_t* next;
diff --git a/kernel/include/kernel_vma.h b/kernel/include/kernel_vma.h
new file mode 100644
index 0000000..af423a4
--- /dev/null
+++ b/kernel/include/kernel_vma.h
@@ -0,0 +1,6 @@
+#ifndef KERNEL_VMA_H
+#define KERNEL_VMA_H
+
+#define KERNEL_VMA 0xffffffff80000000
+
+#endif
diff --git a/kernel/include/paging.h b/kernel/include/paging.h
index 8f69224..71552d1 100644
--- a/kernel/include/paging.h
+++ b/kernel/include/paging.h
@@ -8,7 +8,6 @@
#define FLAG_WRITABLE 0x2
#define FLAG_USER 0x4
#define FLAG_HUGE 0x80
-#define KERNEL_VMA 0xc0000000
void init_paging(void);
void map_addr(uint64_t virt, uint64_t phys, uint32_t flags);
diff --git a/kernel/src/boot/boot.S b/kernel/src/boot/boot.S
index a96be00..704acbf 100644
--- a/kernel/src/boot/boot.S
+++ b/kernel/src/boot/boot.S
@@ -1,99 +1,60 @@
.code32
.extern begin_long_mode
-.set KERNEL_VMA, 0xc0000000
+.section .boot32.text, "a"
-.section .boot.text, "a"
.global _start
_start:
cli
- mov $stack_top - KERNEL_VMA, %esp
+ mov $stack_top, %esp
pushl $0
pushl %eax
pushl $0
pushl %ebx
- call check_multiboot
- call check_cpuid
- call check_long_mode
-
call setup_page_tables
call enable_paging
- addl $KERNEL_VMA, %esp
- mov $4f, %ecx
- jmp *%ecx
-
-check_multiboot:
- cmp $0x36d76289, %eax
- jne no_multiboot
-
- ret
-
-check_cpuid:
- pushfl
- pop %eax
- mov %eax, %ecx
- xor $1<<21, %eax
- push %eax
- popfl
- pushfl
- pop %eax
- push %ecx
- popfl
- cmp %eax, %ecx
- je no_cpuid
-
- ret
-
-check_long_mode:
- mov $0x80000000, %eax
- cpuid
- cmp $0x80000001, %eax
- jb no_long_mode
-
- mov $0x80000001, %eax
- cpuid
- test $1<<29, %edx
- jz no_long_mode
-
- ret
+ lgdt gdtp
+ ljmp $0x08, $begin_long_mode
setup_page_tables:
- mov $pt_lvl3 - KERNEL_VMA, %eax
- or $0x3, %eax
- mov %eax, pt_lvl4 - KERNEL_VMA
-
- // 0x00000000 - 0x00200000 : 0x00000000 - 0x00200000
- mov $pt_lvl2 - KERNEL_VMA, %eax
+// first 2mb
+ mov $pt_lvl3, %eax
or $0x3, %eax
- mov %eax, pt_lvl3 - KERNEL_VMA
+ mov %eax, pt_lvl4
- // 0xc0000000 - 0xc0200000 : 0xc0000000 - 0xc0200000
- mov $pt_lvl2_hh - KERNEL_VMA, %eax
+ mov $pt_lvl2, %eax
or $0x3, %eax
- mov %eax, pt_lvl3 + 24 - KERNEL_VMA
+ mov %eax, pt_lvl3
-// first 2mb
xor %ecx, %ecx
1:
movl $0x00200000, %eax
mul %ecx
or $0b10000011, %eax
- movl $pt_lvl2 - KERNEL_VMA, %edx
+ movl $pt_lvl2, %edx
leal (%edx, %ecx, 8), %edx
movl %eax, (%edx)
inc %ecx
cmp $1, %ecx
jne 1b
-// first 2mb in higher_half
+// first 2mb in hh
+ mov $pt_lvl3_hh, %eax
+ or $0x3, %eax
+ mov %eax, pt_lvl4 + 4096 - 8
+
+ mov $pt_lvl2_hh, %eax
+ or $0x3, %eax
+ mov %eax, pt_lvl3_hh + 4096 - 16
+
xor %ecx, %ecx
2:
movl $0x00200000, %eax
mul %ecx
or $0b10000011, %eax
- movl $pt_lvl2_hh - KERNEL_VMA, %edx
+ movl $pt_lvl2_hh, %edx
leal (%edx, %ecx, 8), %edx
movl %eax, (%edx)
inc %ecx
@@ -115,7 +76,7 @@ enable_paging:
wrmsr
// pt_lvl4
- mov $pt_lvl4 - KERNEL_VMA, %eax
+ mov $pt_lvl4, %eax
mov %eax, %cr3
// enable paging (+ protected mode if not already enabled)
@@ -125,70 +86,43 @@ enable_paging:
ret
-no_multiboot:
- hlt
-no_cpuid:
- hlt
+.section .boot32.rodata
-no_long_mode:
- hlt
-
-.section .text
-4:
- lgdt gdtp
- ljmp $0x08, $begin_long_mode
+gdt:
+gdt_null = . - gdt
+ .quad 0
+gdt_code = . - gdt
+ .long 0xFFFF
+ .byte 0
+ .byte 0x9A
+ .byte 0xAF
+ .byte 0
+gdt_data = . - gdt
+ .long 0xFFFF
+ .byte 0
+ .byte 0xA2
+ .byte 0xAF
+ .byte 0
+gdtp:
+ .word . - gdt - 1
+ .quad gdt
-.section .bss
+.section .boot32.bss
.align 4096
-// stack
-stack_bottom:
- .skip 4096*16
-stack_top:
-
-
-// page tables
pt_lvl4:
.skip 4096
pt_lvl3:
.skip 4096
+pt_lvl3_hh:
+ .skip 4096
pt_lvl2:
.skip 4096
pt_lvl2_hh:
.skip 4096
-
-// Access bits
-.section .rodata
-.set PRESENT, 1 << 7
-.set NOT_SYS, 1 << 4
-.set EXEC, 1 << 3
-.set DC, 1 << 2
-.set RW, 1 << 1
-.set ACCESSED, 1 << 0
-
-// Flags bits
-.set GRAN_4K, 1 << 7
-.set SZ_32, 1 << 6
-.set LONG_MODE, 1 << 5
-
-gdt:
-gdt_null = . - gdt
- .quad 0
-gdt_code = . - gdt
- .long 0xFFFF // Limit & Base (low, bits 0-15)
- .byte 0 // Base (mid, bits 16-23)
- .byte PRESENT | NOT_SYS | EXEC | RW // Access
- .byte GRAN_4K | LONG_MODE | 0xF // Flags & Limit (high, bits 16-19)
- .byte 0 // Base (high, bits 24-31)
-gdt_data = . - gdt
- .long 0xFFFF
- .byte 0
- .byte PRESENT | NOT_SYS | RW
- .byte GRAN_4K | SZ_32 | 0xF
- .byte 0
-gdtp:
- .word . - gdt - 1
- .quad gdt
+stack_bottom:
+ .skip 4096*4
+stack_top:
diff --git a/kernel/src/boot/boot64.S b/kernel/src/boot/boot64.S
index cc79c36..e95f55b 100644
--- a/kernel/src/boot/boot64.S
+++ b/kernel/src/boot/boot64.S
@@ -1,16 +1,25 @@
-.section .text
.code64
+.set KERNEL_VMA, 0xffffffff80000000
+
+.section .boot64.text, "a"
+
.global begin_long_mode
begin_long_mode:
- // reload segment registers
- mov $0x10, %ax
- mov %ax, %ds
- mov %ax, %es
- mov %ax, %ss
- mov %ax, %fs
- mov %ax, %gs
+// xchgw %bx, %bx
+// mov $0x10, %ax
+// mov %ax, %ds
+// mov %ax, %es
+// mov %ax, %ss
+// mov %ax, %fs
+// mov %ax, %gs
+ add $KERNEL_VMA, %rsp
+ movabs $jump_main, %rax
+ jmp *%rax
+
+.section .text
+jump_main:
popq %rdi
popq %rsi
call kernel_main
diff --git a/kernel/src/boot/multiboot2.c b/kernel/src/boot/multiboot2.c
index 1bb9aac..12f3c38 100644
--- a/kernel/src/boot/multiboot2.c
+++ b/kernel/src/boot/multiboot2.c
@@ -8,8 +8,7 @@
#include <libk/string.h>
#include <libk/list.h>
#include <heap.h>
-
-#define KERNEL_VMA 0xc0000000
+#include <kernel_vma.h>
/* https://www.gnu.org/software/grub/manual/multiboot2/html_node/Boot-information-format.html */
diff --git a/kernel/src/cpu/gdt.c b/kernel/src/cpu/gdt.c
index 7ce51f1..743b629 100644
--- a/kernel/src/cpu/gdt.c
+++ b/kernel/src/cpu/gdt.c
@@ -17,7 +17,11 @@ void add_gdt_entry(uint32_t num, uint32_t offset, uint32_t limit, uint8_t access
void add_gdt_tss(uint32_t num, uint64_t offset, uint32_t limit, uint8_t access, uint8_t flags)
{
- add_gdt_entry(num, offset & 0xffffffff, limit, access, flags);
+ uint32_t offset_low = (offset & 0xffffffff);
+ uint32_t offset_high = (uint32_t)(offset >> 32);
+ add_gdt_entry(num, offset_low, limit, access, flags);
+ gdt[num+1].limit = (offset_high & 0xffff);
+ gdt[num+1].offset1 = (uint16_t)(offset_high >> 16);
}
void reload_gdt()
diff --git a/kernel/src/devices/disc.c b/kernel/src/devices/disc.c
index 8d34473..12ed62f 100644
--- a/kernel/src/devices/disc.c
+++ b/kernel/src/devices/disc.c
@@ -3,14 +3,13 @@
#include <libk/string.h>
#include <paging.h>
#include <libk/math.h>
-
-#define KERNEL_VMA 0xc0000000
+#include <kernel_vma.h>
disc_sector_t* disc;
void disc_init()
{
- disc = (disc_sector_t*)(uint64_t)ext2_module->mod_start;
+ disc = (disc_sector_t*)((uint64_t)ext2_module->mod_start + KERNEL_VMA);
if (disc == NULL) {
printf("Error opening disc\n");
}
diff --git a/kernel/src/kernel.ld b/kernel/src/kernel.ld
index 56b5647..f0247b2 100644
--- a/kernel/src/kernel.ld
+++ b/kernel/src/kernel.ld
@@ -1,7 +1,7 @@
ENTRY(_start)
-KERNEL_PMA = 0x00100000;
-KERNEL_VMA = 0xc0000000;
+KERNEL_PMA = 0x0000000000100000;
+KERNEL_VMA = 0xffffffff80000000;
SECTIONS
{
@@ -10,7 +10,10 @@ SECTIONS
.boot BLOCK(4K) : ALIGN(4K)
{
KEEP(*(.multiboot_header))
- *(.boot.text)
+ *(.boot32.text)
+ *(.boot32.rodata)
+ *(.boot32.bss)
+ *(.boot64.text)
}
. += KERNEL_VMA;
diff --git a/kernel/src/libk/stdio.c b/kernel/src/libk/stdio.c
index 61681f0..898f3c6 100644
--- a/kernel/src/libk/stdio.c
+++ b/kernel/src/libk/stdio.c
@@ -30,7 +30,7 @@ inline void print_char(char c)
}
return;
}
- fb_draw_character(main_fb, c, (int32_t)curr_x * 8, (int32_t)curr_y * 16, WHITE, BLACK);
+// fb_draw_character(main_fb, c, (int32_t)curr_x * 8, (int32_t)curr_y * 16, WHITE, BLACK);
curr_x++;
write_serial(c);
diff --git a/kernel/src/main.c b/kernel/src/main.c
index 03e0168..7424f56 100644
--- a/kernel/src/main.c
+++ b/kernel/src/main.c
@@ -27,9 +27,9 @@ int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic)
init_heap();
init_tss();
read_mb2(multiboot_bootinfo, multiboot_magic);
-// disc_init();
-// ext2_init();
-// ls(path_to_inode("/"));
+ disc_init();
+ ext2_init();
+ ls(path_to_inode("/"));
jump_userspace();
for(;;) {
diff --git a/kernel/src/mem/heap.c b/kernel/src/mem/heap.c
index 229933b..e37e003 100644
--- a/kernel/src/mem/heap.c
+++ b/kernel/src/mem/heap.c
@@ -34,12 +34,12 @@ void kheap_add_block(kheap_t* kheap, uint64_t addr, uint32_t size, uint32_t bsiz
bm[i] = 0;
}
- bcnt = upper_div(bcnt, bsize);
- for (size_t i = 0; i < bcnt; i++) {
+ uint32_t bcnt_used = upper_div((bcnt + (uint32_t)sizeof(kheapblock_t)), bsize);
+ for (size_t i = 0; i < bcnt_used; i++) {
bm[i] = 5;
}
- kheapblock->used = bcnt;
+ kheapblock->used = bcnt_used;
}
void* kheap_alloc(kheap_t* kheap, uint32_t size)
@@ -52,6 +52,13 @@ void* kheap_alloc(kheap_t* kheap, uint32_t size)
continue;
}
+ // use heap with bsize 4096 just for that block size
+ bool ind1 = ((size % 4096) == 0);
+ bool ind2 = (kheapblock->bsize == 4096);
+ if (ind1 + ind2 == 1) {
+ continue;
+ }
+
uint32_t bcnt = kheapblock->size / kheapblock->bsize;
uint32_t bneed = upper_div(size, kheapblock->bsize);
uint8_t* bm = (uint8_t*)&kheapblock[1];
@@ -81,7 +88,7 @@ void* kheap_alloc(kheap_t* kheap, uint32_t size)
kheapblock->used += bneed;
- return (void*)(i * kheapblock->bsize + (uintptr_t)&kheapblock[1]);
+ return (void*)(i * kheapblock->bsize + (uintptr_t)&kheapblock[0]);
}
}
printf("Error: there is no remaining memory in kheap\n");
@@ -118,10 +125,6 @@ void kheap_free(kheap_t* kheap, void* pointer)
void init_heap()
{
kheap_init(&main_kheap);
-
- // allocate pages for kheap
- for (size_t i = 0; i < upper_div(HEAP_SIZE, PAGE_SIZE); i++)
- map_addr(HEAP_VMEM_ADDR + i * PAGE_SIZE, HEAP_PMEM_ADDR + i * PAGE_SIZE, FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE);
-
- kheap_add_block(&main_kheap, HEAP_VMEM_ADDR, HEAP_SIZE, HEAP_BLOCK_SIZE);
+ kheap_add_block(&main_kheap, HEAP1_VMEM_ADDR, HEAP1_SIZE, HEAP1_BLOCK_SIZE);
+ kheap_add_block(&main_kheap, HEAP2_VMEM_ADDR, HEAP2_SIZE, HEAP2_BLOCK_SIZE);
}
diff --git a/kernel/src/mem/paging.c b/kernel/src/mem/paging.c
index 19a2c3a..f714f66 100644
--- a/kernel/src/mem/paging.c
+++ b/kernel/src/mem/paging.c
@@ -1,17 +1,15 @@
#include <types.h>
#include <paging.h>
+#include <heap.h>
#include <libk/stdio.h>
-#include <debug.h>
+#include <kernel_vma.h>
void load_pt_lvl4(uint64_t*);
__attribute__((aligned(4096))) uint64_t page_table_lvl4[512];
__attribute__((aligned(4096))) uint64_t page_table_lvl3[512];
-__attribute__((aligned(4096))) uint64_t page_table_lvl2_0[512];
-__attribute__((aligned(4096))) uint64_t page_table_lvl2_1[512];
-__attribute__((aligned(4096))) uint64_t page_table_lvl2_2[512];
-__attribute__((aligned(4096))) uint64_t page_table_lvl2_3[512];
+__attribute__((aligned(4096))) uint64_t page_table_lvl2[512];
void map_addr(uint64_t virt, uint64_t phys, uint32_t flags)
{
@@ -24,38 +22,35 @@ void map_addr(uint64_t virt, uint64_t phys, uint32_t flags)
size_t pt_lvl2_i = (virt >> 21) % 0x200; // 2mb entry
// size_t pt_lvl1_i = (virt >> 12) % 0x200; // 4kb entry
- // first 4gb
- if (pt_lvl4_i == 0) {
- switch(pt_lvl3_i) {
- case 0:
- page_table_lvl2_0[pt_lvl2_i] = phys | flags;
- break;
- case 1:
- page_table_lvl2_1[pt_lvl2_i] = phys | flags;
- break;
- case 2:
- page_table_lvl2_2[pt_lvl2_i] = phys | flags;
- break;
- case 3:
- page_table_lvl2_3[pt_lvl2_i] = phys | flags;
- break;
- }
+ uint64_t* pt_lvl3 = (uint64_t*)(page_table_lvl4[pt_lvl4_i] + KERNEL_VMA);
+ if (!((uint64_t)pt_lvl3 & FLAG_PRESENT)) {
+ pt_lvl3 = (uint64_t*)kalloc(4096);
+ page_table_lvl4[pt_lvl4_i] = ((uint64_t)pt_lvl3 - KERNEL_VMA) | flags;
+ } else {
+ pt_lvl3 = (uint64_t*)((uint64_t)pt_lvl3 - (uint64_t)pt_lvl3 % 4096);
}
+
+ uint64_t* pt_lvl2 = (uint64_t*)(pt_lvl3[pt_lvl3_i] + KERNEL_VMA);
+ if (!((uint64_t)pt_lvl2 & FLAG_PRESENT)) {
+ pt_lvl2 = (uint64_t*)kalloc(4096);
+ pt_lvl3[pt_lvl3_i] = ((uint64_t)pt_lvl2 - KERNEL_VMA) | flags;
+ } else {
+ pt_lvl2 -= (uint64_t)pt_lvl2 % 4096;
+ }
+
+ pt_lvl2[pt_lvl2_i] = virt | flags;
}
void init_paging(void)
{
- page_table_lvl4[0] = (uint64_t)page_table_lvl3 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA;
- page_table_lvl3[0] = (uint64_t)page_table_lvl2_0 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA;
- page_table_lvl3[1] = (uint64_t)page_table_lvl2_1 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA;
- page_table_lvl3[2] = (uint64_t)page_table_lvl2_2 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA;
- page_table_lvl3[3] = (uint64_t)page_table_lvl2_3 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA;
-
- // higher half map first 6mb
- for (size_t i = 0; i < 3; i++) {
- map_addr(KERNEL_VMA + PAGE_SIZE * i, 0x00000000 + PAGE_SIZE * i, FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER + FLAG_HUGE);
+ page_table_lvl4[511] = (uint64_t)page_table_lvl3 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA;
+ page_table_lvl3[510] = (uint64_t)page_table_lvl2 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA;
+ // 16mb kernel + 32mb heap
+ for (size_t i = 0; i < 24; i++) {
+ page_table_lvl2[i] = (uint64_t)0x0 + PAGE_SIZE * i + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER + FLAG_HUGE;
}
+
load_pt_lvl4(page_table_lvl4);
}
diff --git a/kernel/src/mem/paging_asm.S b/kernel/src/mem/paging_asm.S
index c7e11f3..e7c7814 100644
--- a/kernel/src/mem/paging_asm.S
+++ b/kernel/src/mem/paging_asm.S
@@ -1,6 +1,6 @@
.section .text
-.set KERNEL_VMA, 0xc0000000
+.set KERNEL_VMA, 0xffffffff80000000
.global load_pt_lvl4
load_pt_lvl4:
@@ -8,7 +8,7 @@ load_pt_lvl4:
mov %rsp, %rbp
push %r12
- mov $KERNEL_VMA, %r12
+ movabs $KERNEL_VMA, %r12
sub %r12, %rdi
mov %rdi, %cr3
pop %r12
diff --git a/kernel/src/misc/debug.c b/kernel/src/misc/debug.c
deleted file mode 100644
index d244d7a..0000000
--- a/kernel/src/misc/debug.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <debug.h>
-
-void bochs_breakpoint(void)
-{
- __asm__ volatile ("xchgw %bx, %bx;");
-}
diff --git a/kernel/src/sys/userspace_asm.S b/kernel/src/sys/userspace_asm.S
index 5817a8c..02181bd 100644
--- a/kernel/src/sys/userspace_asm.S
+++ b/kernel/src/sys/userspace_asm.S
@@ -26,6 +26,6 @@ jump_userspace:
mov $0x00100008, %edx
wrmsr
- mov $begin_userspace, %ecx
+ movabs $begin_userspace, %rcx
mov $0x202, %r11
sysretq