aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/kernel/boot.asm12
-rw-r--r--src/kernel/gdt/gdt.c17
-rw-r--r--src/kernel/gdt/gdt.h4
-rw-r--r--src/kernel/interrupts/isr.c2
-rw-r--r--src/kernel/kernel.c9
-rw-r--r--src/kernel/lib/stdlib/liballoc.c18
-rw-r--r--src/kernel/paging/paging.c23
-rw-r--r--src/kernel/paging/paging.h2
-rw-r--r--src/kernel/syscall/syscall.c5
-rw-r--r--src/kernel/system.c1
-rw-r--r--src/userspace/main.c3
-rw-r--r--src/userspace/mlibc/stdio/printf.c6
-rw-r--r--src/userspace/start.asm4
13 files changed, 76 insertions, 30 deletions
diff --git a/src/kernel/boot.asm b/src/kernel/boot.asm
index 6b95f4c..85d4254 100644
--- a/src/kernel/boot.asm
+++ b/src/kernel/boot.asm
@@ -29,7 +29,11 @@ section .text
global jump_userspace
jump_userspace:
cli
- mov ebx, dword [esp + 4]
+ push ebp
+ mov ebp, esp
+ mov edx, dword [esp + 0xC]
+ mov esp, edx
+ push 0xABCDEF
mov ax, 0x23
mov ds, ax
@@ -48,10 +52,12 @@ section .text
push eax
push 0x1B
- push ebx
- mov ebp, ebx
+ push dword [ebp + 8]
iret
+ pop ebp
+ ret
+
section .end_section
global ASM_KERNEL_END
ASM_KERNEL_END:
diff --git a/src/kernel/gdt/gdt.c b/src/kernel/gdt/gdt.c
index 49d5ce6..435528a 100644
--- a/src/kernel/gdt/gdt.c
+++ b/src/kernel/gdt/gdt.c
@@ -2,7 +2,7 @@
#include <kernel/gdt/gdt.h>
#include <kernel/system.h>
#include <kernel/lib/lib.h>
-#include <kernel/lib/stdlib/liballoc.h>
+#include <kernel/lib/stdlib.h>
struct gdt_entry {
unsigned short limit_low;
@@ -93,7 +93,7 @@ void gdt_install()
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
// Write TSS
- tss_write(5, 0x10);
+ tss_write(5, 0x10, 0x0);
// Remove old GDT and install the new changes!
gdt_flush();
@@ -101,7 +101,7 @@ void gdt_install()
vga_log("Installed Global Descriptor Table");
}
-void tss_write(int32_t num, uint16_t ss0)
+void tss_write(int32_t num, uint16_t ss0, uint32_t esp0)
{
uint32_t base = (uint32_t) &tss_entry;
uint32_t limit = base + sizeof(tss_entry);
@@ -111,13 +111,20 @@ void tss_write(int32_t num, uint16_t ss0)
memset(&tss_entry, 0, sizeof(tss_entry));
tss_entry.ss0 = ss0;
- tss_entry.iomap_base = sizeof(struct tss_entry_struct);
+ tss_entry.esp0 = esp0;
tss_entry.cs = 0x0b;
tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x13;
+
+ tss_entry.iomap_base = sizeof(struct tss_entry_struct);
}
void tss_flush(void)
{
- tss_entry.esp0 = 4096 + (uint32_t) kmalloc(4096);
+ tss_entry.esp0 = 4096 + (uint32_t) umalloc(4096);
asm volatile ("ltr %%ax": : "a" (0x2B));
+}
+
+void set_kernel_stack(uintptr_t stack)
+{
+ tss_entry.esp0 = stack;
} \ No newline at end of file
diff --git a/src/kernel/gdt/gdt.h b/src/kernel/gdt/gdt.h
index da36445..0e77103 100644
--- a/src/kernel/gdt/gdt.h
+++ b/src/kernel/gdt/gdt.h
@@ -6,8 +6,10 @@
*/
void gdt_install();
-void tss_write(int32_t num, uint16_t ss0);
+void tss_write(int32_t num, uint16_t ss0, uint32_t esp0);
void tss_flush();
+void set_kernel_stack(uintptr_t stack);
+
#endif
diff --git a/src/kernel/interrupts/isr.c b/src/kernel/interrupts/isr.c
index eb932b2..8b2a9e5 100644
--- a/src/kernel/interrupts/isr.c
+++ b/src/kernel/interrupts/isr.c
@@ -3,6 +3,7 @@
#include <kernel/system.h>
#include <kernel/lib/string.h>
#include <kernel/lib/stdio.h>
+#include <kernel/paging/paging.h>
// Install ISRs in IDT
void isrs_install()
@@ -116,6 +117,7 @@ void fault_handler(struct regs *r)
r->eip, r->eax, r->ebx, r->ecx, r->edx, r->esp, faulting_address, r->eflags, r->err_code, r->int_no,
exception_messages[r->int_no]
);
+ serial_printf("%d", paging_get_flags(faulting_address));
// halt_loop(); // Idk loop?
char *message = (char *) exception_messages[r->int_no];
strcat(message, " Exception");
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index d8f8c66..b2b7ada 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -60,18 +60,19 @@ void kernel_main()
info("Switching to user mode...");
syscalls_install();
tss_flush();
- uint32_t userspace = paging_alloc_pages(10);
- paging_set_user(userspace, 10);
+ uint32_t userspace = (uint32_t) umalloc(8096);
+ paging_switch_directory(1);
if (boot_drive_id == 0xE0) {
char *user_p[] = {"USER.BIN"};
struct iso9660_entity *user_e = ISO9660_get(user_p, 1);
if (!user_e) panic("Userspace binary not found!");
ATAPI_granular_read(1 + (user_e->length / 2048), user_e->lba, (uint8_t *) (userspace + 4096));
kfree(user_e);
- jump_userspace(userspace + 4096);
+ jump_userspace(userspace + 4096, userspace + 4096);
} else {
marfs_read_whole_file(4, (uint8_t *) (userspace + 4096));
- jump_userspace(userspace + 4096);
+ paging_switch_directory(1);
+ jump_userspace(userspace + 4096, userspace + 4096);
}
panic("This should NOT happen!");
diff --git a/src/kernel/lib/stdlib/liballoc.c b/src/kernel/lib/stdlib/liballoc.c
index e05cc24..c1a5de1 100644
--- a/src/kernel/lib/stdlib/liballoc.c
+++ b/src/kernel/lib/stdlib/liballoc.c
@@ -472,6 +472,7 @@ void *krealloc(void *p, size_t size)
void *umalloc(size_t req_size)
{
+ paging_switch_directory(1);
int started_bet = 0;
unsigned long long best_size = 0;
void *p = NULL;
@@ -497,6 +498,7 @@ void *umalloc(size_t req_size)
l_mem_root_user = allocate_new_page(size, 1);
if (l_mem_root_user == NULL) {
liballoc_unlock();
+ paging_switch_directory(0);
return NULL;
}
}
@@ -554,6 +556,7 @@ void *umalloc(size_t req_size)
p = (void *) ((uintptr_t) (maj->first) + sizeof(struct liballoc_minor));
ALIGN(p);
liballoc_unlock();
+ paging_switch_directory(0);
return p;
}
@@ -576,6 +579,7 @@ void *umalloc(size_t req_size)
p = (void *) ((uintptr_t) (maj->first) + sizeof(struct liballoc_minor));
ALIGN(p);
liballoc_unlock();
+ paging_switch_directory(0);
return p;
}
@@ -601,6 +605,7 @@ void *umalloc(size_t req_size)
p = (void *) ((uintptr_t) min + sizeof(struct liballoc_minor));
ALIGN(p);
liballoc_unlock();
+ paging_switch_directory(0);
return p;
}
}
@@ -626,6 +631,7 @@ void *umalloc(size_t req_size)
p = (void *) ((uintptr_t) new_min + sizeof(struct liballoc_minor));
ALIGN(p);
liballoc_unlock();
+ paging_switch_directory(0);
return p;
}
}
@@ -649,16 +655,19 @@ void *umalloc(size_t req_size)
liballoc_unlock();
+ paging_switch_directory(0);
return NULL;
}
void ufree(void *ptr)
{
+ paging_switch_directory(1);
struct liballoc_minor *min;
struct liballoc_major *maj;
if (ptr == NULL) {
l_warning_count_user += 1;
+ paging_switch_directory(0);
return;
}
@@ -677,6 +686,7 @@ void ufree(void *ptr)
}
liballoc_unlock();
+ paging_switch_directory(0);
return;
}
@@ -703,10 +713,12 @@ void ufree(void *ptr)
}
}
liballoc_unlock();
+ paging_switch_directory(0);
}
void *ucalloc(size_t nobj, size_t size)
{
+ paging_switch_directory(1);
int real_size;
void *p;
@@ -716,17 +728,20 @@ void *ucalloc(size_t nobj, size_t size)
liballoc_memset(p, 0, real_size);
+ paging_switch_directory(0);
return p;
}
void *urealloc(void *p, size_t size)
{
+ paging_switch_directory(1);
void *ptr;
struct liballoc_minor *min;
unsigned int real_size;
if (size == 0) {
ufree(p);
+ paging_switch_directory(0);
return NULL;
}
@@ -746,6 +761,7 @@ void *urealloc(void *p, size_t size)
}
liballoc_unlock();
+ paging_switch_directory(0);
return NULL;
}
@@ -754,6 +770,7 @@ void *urealloc(void *p, size_t size)
if (real_size >= size) {
min->req_size = size;
liballoc_unlock();
+ paging_switch_directory(0);
return p;
}
@@ -763,5 +780,6 @@ void *urealloc(void *p, size_t size)
liballoc_memcpy(ptr, p, real_size);
ufree(p);
+ paging_switch_directory(0);
return ptr;
} \ No newline at end of file
diff --git a/src/kernel/paging/paging.c b/src/kernel/paging/paging.c
index 6f7833d..c4a2940 100644
--- a/src/kernel/paging/paging.c
+++ b/src/kernel/paging/paging.c
@@ -12,11 +12,8 @@ uint32_t kernel_page_tables[1024][1024] __attribute__((aligned(4096)));
uint32_t user_page_directory[1024] __attribute__((aligned(4096)));
uint32_t user_page_tables[1024][1024] __attribute__((aligned(4096)));
-void paging_install()
+void paging_init()
{
- current_page_directory = kernel_page_directory;
- current_page_tables = kernel_page_tables;
-
for (uint32_t i = 0; i < 1024; i++) {
for (uint32_t j = 0; j < 1024; j++) {
current_page_tables[i][j] = ((j * 0x1000) + (i * 0x400000)) | PT_RW;
@@ -27,7 +24,19 @@ void paging_install()
current_page_directory[i] = ((uint32_t) current_page_tables[i]) | PD_RW | PD_PRESENT;
}
- paging_set_present(0, memory_get_all() >> 2); // /4
+ paging_set_present(0, memory_get_all() >> 3); // /4
+}
+
+void paging_install()
+{
+ // User paging
+ paging_switch_directory(1);
+ paging_init();
+ paging_set_user(0, memory_get_all() >> 3);
+
+ // Kernel paging
+ paging_switch_directory(0);
+ paging_init();
paging_set_used(0, ((uint32_t) ASM_KERNEL_END >> 12) + 1); // /4096
paging_enable();
@@ -44,9 +53,9 @@ void paging_disable()
paging_enabled = 0;
}
-void paging_switch_directory()
+void paging_switch_directory(int user)
{
- if (current_page_tables == kernel_page_tables) {
+ if (user == 1) {
current_page_tables = user_page_tables;
current_page_directory = user_page_directory;
} else {
diff --git a/src/kernel/paging/paging.h b/src/kernel/paging/paging.h
index 684c3b2..b75bbe3 100644
--- a/src/kernel/paging/paging.h
+++ b/src/kernel/paging/paging.h
@@ -29,7 +29,7 @@ void paging_enable();
void paging_disable();
-void paging_switch_directory();
+void paging_switch_directory(int user);
void paging_map(uint32_t phy, uint32_t virt, uint16_t flags);
diff --git a/src/kernel/syscall/syscall.c b/src/kernel/syscall/syscall.c
index 7ca7f99..93abc83 100644
--- a/src/kernel/syscall/syscall.c
+++ b/src/kernel/syscall/syscall.c
@@ -3,9 +3,12 @@
#include <kernel/interrupts/interrupts.h>
#include <kernel/system.h>
#include <kernel/lib/stdio.h>
+#include <kernel/paging/paging.h>
typedef uint32_t (*syscall_func)(unsigned int, ...);
+extern void jump_userspace();
+
uint32_t (*syscalls[])() = {
[0] = (uint32_t (*)()) halt_loop, // DEBUG!
[1] = sys_write,
@@ -19,6 +22,7 @@ uint32_t (*syscalls[])() = {
void syscall_handler(struct regs *r)
{
+ paging_switch_directory(0);
serial_printf("Received syscall!");
if (r->eax >= sizeof(syscalls) / sizeof(*syscalls))
@@ -31,6 +35,7 @@ void syscall_handler(struct regs *r)
//serial_printf("[SYSCALL] %d (0x%x) 0x%x 0x%x 0x%x 0x%x 0x%x", r->eax, location, r->ebx, r->ecx, r->edx, r->esi, r->edi);
r->eax = location(r->ebx, r->ecx, r->edx, r->esi, r->edi);
+ paging_switch_directory(1);
}
void syscalls_install()
diff --git a/src/kernel/system.c b/src/kernel/system.c
index c37c890..c01fb46 100644
--- a/src/kernel/system.c
+++ b/src/kernel/system.c
@@ -106,7 +106,6 @@ void assert(int x)
void halt_loop()
{
- serial_printf("\n!!! HALT !!!");
asm ("cli");
loop:
asm ("hlt");
diff --git a/src/userspace/main.c b/src/userspace/main.c
index 6149573..c2307a8 100644
--- a/src/userspace/main.c
+++ b/src/userspace/main.c
@@ -14,6 +14,9 @@ void user_main()
char text[] = "> Successfully switched to usermode!\n";
printf(text);
+ // TODO: PLEASE
+ printf("If this message shows up, I'll be happy.\n");
+
while (1) {
char *input = readline();
if (starts_with(input, "ls")) {
diff --git a/src/userspace/mlibc/stdio/printf.c b/src/userspace/mlibc/stdio/printf.c
index b582897..5617d03 100644
--- a/src/userspace/mlibc/stdio/printf.c
+++ b/src/userspace/mlibc/stdio/printf.c
@@ -1,14 +1,10 @@
#include <stdarg.h>
#include <mlibc/stdio.h>
-#include <mlibc/string.h>
-#include <mlibc/stdlib.h>
void printf(const char *fmt, ...)
{
- char *format = (char *) malloc(strlen(fmt));
- strcpy(format, fmt);
va_list args;
va_start(args, fmt);
- vprintf(format, args);
+ vprintf(fmt, args);
va_end(args);
} \ No newline at end of file
diff --git a/src/userspace/start.asm b/src/userspace/start.asm
index 7348825..c6bb2a0 100644
--- a/src/userspace/start.asm
+++ b/src/userspace/start.asm
@@ -4,6 +4,4 @@ section .text
global _start
extern user_main
_start:
- mov esp, ebp
- call user_main
- jmp $ \ No newline at end of file
+ call user_main \ No newline at end of file