summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksa Vuckovic <aleksav013@gmail.com>2022-09-05 23:54:12 +0200
committerAleksa Vuckovic <aleksav013@gmail.com>2022-09-07 17:46:10 +0200
commit956bb743a3ba6939aaff2372fc45628cda6a9840 (patch)
tree0d1fd304eb584c892e28e43bbc851cf66786d9da
parent59f86fe8dd237e50c7fea03b506125e3abff0157 (diff)
userspace finally working
-rw-r--r--.gitignore3
-rw-r--r--Makefile2
-rw-r--r--kernel/include/heap.h6
-rw-r--r--kernel/include/paging.h1
-rw-r--r--kernel/src/boot/boot.S2
-rw-r--r--kernel/src/boot/boot64.S12
-rw-r--r--kernel/src/cpu/gdt.c12
-rw-r--r--kernel/src/cpu/irq_stub.S4
-rw-r--r--kernel/src/cpu/registers.c57
-rw-r--r--kernel/src/cpu/tss.c9
-rw-r--r--kernel/src/main.c9
-rw-r--r--kernel/src/mem/paging.c14
-rw-r--r--kernel/src/sys/userspace_asm.S24
13 files changed, 114 insertions, 41 deletions
diff --git a/.gitignore b/.gitignore
index 5209157..70632d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,5 @@ kernel.iso
**/*.o
**/*.d
isodir
-xbochs.log
+*log
bx_enh_dbg.ini
-serial.log
diff --git a/Makefile b/Makefile
index 761a4a2..dbce783 100644
--- a/Makefile
+++ b/Makefile
@@ -75,6 +75,6 @@ endif
clean:
@find -name "*.o" -exec rm {} \;
@find -name "*.d" -exec rm {} \;
- @rm -f kernel.iso $K/kernel.bin xbochs.log bx_enh_dbg.ini
+ @rm -f kernel.iso $K/kernel.bin xbochs.log bx_enh_dbg.ini log serial.log
@rm -rf isodir
@$(MAKE) umount
diff --git a/kernel/include/heap.h b/kernel/include/heap.h
index 62d3b6f..b2d9a00 100644
--- a/kernel/include/heap.h
+++ b/kernel/include/heap.h
@@ -3,9 +3,9 @@
#include <types.h>
-#define HEAP_VMEM_ADDR 0xc1000000
-#define HEAP_PMEM_ADDR 0x01000000
-#define HEAP_SIZE 0x01000000
+#define HEAP_VMEM_ADDR 0xc2000000
+#define HEAP_PMEM_ADDR 0x02000000
+#define HEAP_SIZE 0x02000000
#define HEAP_BLOCK_SIZE 0x00000010
struct kheapblock_t {
diff --git a/kernel/include/paging.h b/kernel/include/paging.h
index 7c9fcd5..8f69224 100644
--- a/kernel/include/paging.h
+++ b/kernel/include/paging.h
@@ -6,6 +6,7 @@
#define PAGE_SIZE 0x00200000
#define FLAG_PRESENT 0x1
#define FLAG_WRITABLE 0x2
+#define FLAG_USER 0x4
#define FLAG_HUGE 0x80
#define KERNEL_VMA 0xc0000000
diff --git a/kernel/src/boot/boot.S b/kernel/src/boot/boot.S
index e0c5326..a96be00 100644
--- a/kernel/src/boot/boot.S
+++ b/kernel/src/boot/boot.S
@@ -145,7 +145,7 @@ no_long_mode:
// stack
stack_bottom:
- .skip 4096*4
+ .skip 4096*16
stack_top:
diff --git a/kernel/src/boot/boot64.S b/kernel/src/boot/boot64.S
index 68eae38..cc79c36 100644
--- a/kernel/src/boot/boot64.S
+++ b/kernel/src/boot/boot64.S
@@ -4,12 +4,12 @@
.global begin_long_mode
begin_long_mode:
// reload segment registers
- mov $0x10, %eax
- mov %eax, %ss
- mov %eax, %ds
- mov %eax, %es
- mov %eax, %fs
- mov %eax, %gs
+ mov $0x10, %ax
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %ss
+ mov %ax, %fs
+ mov %ax, %gs
popq %rdi
popq %rsi
diff --git a/kernel/src/cpu/gdt.c b/kernel/src/cpu/gdt.c
index b4f1ec0..7ce51f1 100644
--- a/kernel/src/cpu/gdt.c
+++ b/kernel/src/cpu/gdt.c
@@ -23,10 +23,13 @@ void add_gdt_tss(uint32_t num, uint64_t offset, uint32_t limit, uint8_t access,
void reload_gdt()
{
__asm__ volatile (
+ // reload segment registers
"mov $0x10, %ax;"
"mov %ax, %ds;"
"mov %ax, %es;"
"mov %ax, %ss;"
+ "mov %ax, %fs;"
+ "mov %ax, %gs;"
);
}
@@ -42,12 +45,11 @@ void init_gdt()
gdt_pointer.size = sizeof(gdt) - 1;
add_gdt_entry(0, 0, 0, 0, 0);
- add_gdt_entry(1, 0, 0xfffff, 0x9a, 0xa);
- add_gdt_entry(2, 0, 0xfffff, 0x92, 0xc);
- add_gdt_entry(3, 0, 0xfffff, 0xfa, 0xa);
- add_gdt_entry(4, 0, 0xfffff, 0xf2, 0xc);
+ add_gdt_entry(1, 0, 0xfffff, 0x9a, 0xa); // code ring0
+ add_gdt_entry(2, 0, 0xfffff, 0x92, 0xc); // data ring0
+ add_gdt_entry(3, 0, 0xfffff, 0xf2, 0xc); // data ring3
+ add_gdt_entry(4, 0, 0xfffff, 0xfa, 0xa); // code ring3
add_gdt_tss(5, (uint64_t)&tss, sizeof(tss_type), 0x89, 0);
load_gdt(&gdt_pointer);
- init_tss();
}
diff --git a/kernel/src/cpu/irq_stub.S b/kernel/src/cpu/irq_stub.S
index 9b2b2d8..5a8149c 100644
--- a/kernel/src/cpu/irq_stub.S
+++ b/kernel/src/cpu/irq_stub.S
@@ -24,7 +24,6 @@
pop %rax
.endm
-
.macro isr_no_error number
.global isr\number
isr\number:
@@ -38,11 +37,12 @@ isr\number:
.macro isr_error number
.global isr\number
isr\number:
- pop %rdi
pushall
+ mov 0x50(%rsp), %rdi
cld
call isr\number\()_handler
popall
+ add $8, %rsp
iretq
.endm
diff --git a/kernel/src/cpu/registers.c b/kernel/src/cpu/registers.c
new file mode 100644
index 0000000..7dc22d4
--- /dev/null
+++ b/kernel/src/cpu/registers.c
@@ -0,0 +1,57 @@
+#include <types.h>
+#include <libk/stdio.h>
+
+struct registers_t {
+ uint64_t rax;
+ uint64_t rbx;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t rsp;
+ uint64_t rbp;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t rip;
+ uint16_t cs;
+ uint16_t ds;
+ uint16_t ss;
+ uint16_t es;
+ uint16_t fs;
+ uint16_t gs;
+};
+typedef struct registers_t registers_t;
+
+void print_reg(registers_t* registers)
+{
+ printf("printing registers:");
+ printf("rax: %x", registers->rax);
+ printf("rbx: %x", registers->rbx);
+ printf("rcx: %x", registers->rcx);
+ printf("rdx: %x", registers->rdx);
+ printf("rsi: %x", registers->rsi);
+ printf("rdi: %x", registers->rdi);
+ printf("rsp: %x", registers->rsp);
+ printf("rbp: %x", registers->rbp);
+ printf("r8: %x", registers->r8);
+ printf("r9: %x", registers->r9);
+ printf("r10: %x", registers->r10);
+ printf("r11: %x", registers->r11);
+ printf("r12: %x", registers->r12);
+ printf("r13: %x", registers->r13);
+ printf("r14: %x", registers->r14);
+ printf("r15: %x", registers->r15);
+ printf("rip: %x", registers->rip);
+ printf("cs: %x", registers->cs);
+ printf("ds: %x", registers->ds);
+ printf("ss: %x", registers->ss);
+ printf("es: %x", registers->es);
+ printf("fs: %x", registers->fs);
+ printf("gs: %x", registers->gs);
+}
diff --git a/kernel/src/cpu/tss.c b/kernel/src/cpu/tss.c
index c7f9dc2..843c114 100644
--- a/kernel/src/cpu/tss.c
+++ b/kernel/src/cpu/tss.c
@@ -1,15 +1,22 @@
#include <tss.h>
+#include <heap.h>
+#include <libk/stdio.h>
tss_type tss;
void load_tss()
{
- __asm__ volatile ("mov $0x28, %ax; ltr %ax;");
+ __asm__ volatile ("push %rax; mov $0x28, %ax; ltr %ax; pop %rax;");
}
void init_tss()
{
tss.iopb = sizeof(tss_type);
+ uint64_t stack = (uint64_t)kalloc(4096*4);
+ stack = (uint64_t)kalloc(4096*4) + 8;
+ tss.rsp0_low = (uint32_t)stack;
+ tss.rsp0_high = (uint32_t)(stack >> 32);
load_tss();
+ printf("rsp0 addr in tss: 0x%x\n", stack);
}
diff --git a/kernel/src/main.c b/kernel/src/main.c
index dce9c05..4b0d62a 100644
--- a/kernel/src/main.c
+++ b/kernel/src/main.c
@@ -22,14 +22,15 @@ int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic)
init_serial();
init_gdt();
init_paging();
- init_idt();
init_timer(TICKS_PER_SECOND);
+ init_idt();
init_heap();
read_mb2(multiboot_bootinfo, multiboot_magic);
- disc_init();
- ext2_init();
+ init_tss();
+// disc_init();
+// ext2_init();
// ls(path_to_inode("/"));
-// jump_userspace();
+ jump_userspace();
for(;;) {
__asm__ volatile ("hlt;");
diff --git a/kernel/src/mem/paging.c b/kernel/src/mem/paging.c
index 630fb6d..19a2c3a 100644
--- a/kernel/src/mem/paging.c
+++ b/kernel/src/mem/paging.c
@@ -45,15 +45,15 @@ void map_addr(uint64_t virt, uint64_t phys, uint32_t flags)
void init_paging(void)
{
- page_table_lvl4[0] = (uint64_t)page_table_lvl3 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA;
- page_table_lvl3[0] = (uint64_t)page_table_lvl2_0 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA;
- page_table_lvl3[1] = (uint64_t)page_table_lvl2_1 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA;
- page_table_lvl3[2] = (uint64_t)page_table_lvl2_2 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA;
- page_table_lvl3[3] = (uint64_t)page_table_lvl2_3 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA;
+ 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_HUGE);
+ map_addr(KERNEL_VMA + PAGE_SIZE * i, 0x00000000 + PAGE_SIZE * i, FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER + FLAG_HUGE);
}
load_pt_lvl4(page_table_lvl4);
@@ -65,7 +65,7 @@ void page_fault(uint64_t error)
uint64_t addr;
__asm__ volatile ("mov %%cr2, %0;" : "=r"(addr) : : "memory");
- map_addr(addr, addr, FLAG_PRESENT | FLAG_WRITABLE | FLAG_HUGE);
+ map_addr(addr, addr, FLAG_PRESENT | FLAG_WRITABLE | FLAG_USER | FLAG_HUGE);
printf("address: 0x%x, error code: %d\n", addr, error);
}
diff --git a/kernel/src/sys/userspace_asm.S b/kernel/src/sys/userspace_asm.S
index 5838051..c722df0 100644
--- a/kernel/src/sys/userspace_asm.S
+++ b/kernel/src/sys/userspace_asm.S
@@ -4,17 +4,23 @@
.global jump_userspace
jump_userspace:
- mov $0x23, %ax
+ mov $0x1b, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
- mov %esp, %eax
- push $0x23
- push %rax
- pushf
- push $0x1b
- sub $8, %rsp
- movabs $begin_userspace, %rsp
- iretq
+ mov $0xc0000082, %rcx
+ wrmsr
+ mov $0xc0000080, %rcx
+ rdmsr
+ or $1, %eax
+ wrmsr
+ mov $0xc0000081, %rcx
+ rdmsr
+ mov $0x00100008, %edx
+ wrmsr
+
+ mov $begin_userspace, %ecx
+ mov $0x202, %r11
+ sysretq