Testing paging and entering userland
This commit is contained in:
parent
64f29facc5
commit
98b4afb451
|
@ -124,6 +124,19 @@ _start:
|
||||||
# Set up the stack.
|
# Set up the stack.
|
||||||
mov $stack_top, %esp
|
mov $stack_top, %esp
|
||||||
|
|
||||||
|
# Setup the GDT
|
||||||
|
call gdt_init
|
||||||
|
|
||||||
|
jmp $0x08,$reload_CS
|
||||||
|
|
||||||
|
reload_CS:
|
||||||
|
mov $0x10, %ax
|
||||||
|
mov %ax, %ds
|
||||||
|
mov %ax, %es
|
||||||
|
mov %ax, %fs
|
||||||
|
mov %ax, %gs
|
||||||
|
mov %ax, %ss
|
||||||
|
|
||||||
# Enter the high-level kernel.
|
# Enter the high-level kernel.
|
||||||
call kernel_main
|
call kernel_main
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,9 @@ static void add_exceptions()
|
||||||
entry = generate_entry(true, divide_by_zero, 0xF, 0, 0x8);
|
entry = generate_entry(true, divide_by_zero, 0xF, 0, 0x8);
|
||||||
add_entry(entry, DivisionByZero);
|
add_entry(entry, DivisionByZero);
|
||||||
|
|
||||||
|
entry = generate_entry(true, page_fault, 0xF, 0, 0x8);
|
||||||
|
add_entry(entry, PageFault);
|
||||||
|
|
||||||
entry = generate_entry(true, general_protection_fault, 0xF, 0, 0x8);
|
entry = generate_entry(true, general_protection_fault, 0xF, 0, 0x8);
|
||||||
add_entry(entry, GenerProtFault);
|
add_entry(entry, GenerProtFault);
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,14 @@ static void stack_trace()
|
||||||
|
|
||||||
__attribute__((interrupt)) void divide_by_zero(struct interrupt_frame*)
|
__attribute__((interrupt)) void divide_by_zero(struct interrupt_frame*)
|
||||||
{
|
{
|
||||||
|
asm("cli");
|
||||||
terminal_writestring("Yo dude u cant divide by zero yao\n");
|
terminal_writestring("Yo dude u cant divide by zero yao\n");
|
||||||
while (1) { }
|
while (1) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void general_protection_fault(struct interrupt_frame*)
|
__attribute__((interrupt)) void general_protection_fault(struct interrupt_frame*)
|
||||||
{
|
{
|
||||||
|
asm("cli");
|
||||||
terminal_writestring("GPF handler called\n");
|
terminal_writestring("GPF handler called\n");
|
||||||
while (1) {
|
while (1) {
|
||||||
asm("cli");
|
asm("cli");
|
||||||
|
@ -38,6 +40,7 @@ __attribute__((interrupt)) void general_protection_fault(struct interrupt_frame*
|
||||||
|
|
||||||
__attribute__((interrupt)) void double_fault(struct interrupt_frame*)
|
__attribute__((interrupt)) void double_fault(struct interrupt_frame*)
|
||||||
{
|
{
|
||||||
|
asm("cli");
|
||||||
stack_trace();
|
stack_trace();
|
||||||
terminal_writestring("2 Errors in a row, u better behave naughty naughty\n");
|
terminal_writestring("2 Errors in a row, u better behave naughty naughty\n");
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -48,10 +51,18 @@ __attribute__((interrupt)) void double_fault(struct interrupt_frame*)
|
||||||
|
|
||||||
__attribute__((interrupt)) void exception(struct interrupt_frame*)
|
__attribute__((interrupt)) void exception(struct interrupt_frame*)
|
||||||
{
|
{
|
||||||
|
asm("cli");
|
||||||
terminal_writestring("Some weird error code stuff\n");
|
terminal_writestring("Some weird error code stuff\n");
|
||||||
while (1) { }
|
while (1) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((interrupt)) void page_fault(struct interrupt_frame*)
|
||||||
|
{
|
||||||
|
asm("cli");
|
||||||
|
terminal_writestring("Page Fault\n");
|
||||||
|
while (1) { }
|
||||||
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame*)
|
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame*)
|
||||||
{
|
{
|
||||||
terminal_writestring("Keyboard Interrupt\n");
|
terminal_writestring("Keyboard Interrupt\n");
|
||||||
|
|
|
@ -11,6 +11,7 @@ struct interrupt_frame {
|
||||||
__attribute__((interrupt)) void divide_by_zero(struct interrupt_frame* frame);
|
__attribute__((interrupt)) void divide_by_zero(struct interrupt_frame* frame);
|
||||||
__attribute__((interrupt)) void general_protection_fault(struct interrupt_frame* frame);
|
__attribute__((interrupt)) void general_protection_fault(struct interrupt_frame* frame);
|
||||||
__attribute__((interrupt)) void double_fault(struct interrupt_frame* frame);
|
__attribute__((interrupt)) void double_fault(struct interrupt_frame* frame);
|
||||||
|
__attribute__((interrupt)) void page_fault(struct interrupt_frame* frame);
|
||||||
|
|
||||||
__attribute__((interrupt)) void exception(struct interrupt_frame* frame);
|
__attribute__((interrupt)) void exception(struct interrupt_frame* frame);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include <kernel/paging.h>
|
#include <kernel/paging.h>
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
|
#include <debugging.h>
|
||||||
|
#include <kernel/heap.h>
|
||||||
|
|
||||||
struct x86_Page_Directory {
|
struct x86_Page_Directory {
|
||||||
bool present: 1;
|
bool present: 1;
|
||||||
|
@ -15,7 +17,7 @@ struct x86_Page_Directory {
|
||||||
bool available_2: 1;
|
bool available_2: 1;
|
||||||
bool page_size: 1;
|
bool page_size: 1;
|
||||||
uint8_t available_1 : 4;
|
uint8_t available_1 : 4;
|
||||||
uint32_t address : 20; // Multiply by 0x1000
|
uintptr_t address : 20; // Multiply by 0x1000
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct x86_Page_Table {
|
struct x86_Page_Table {
|
||||||
|
@ -29,22 +31,66 @@ struct x86_Page_Table {
|
||||||
bool page_attribute_table: 1;
|
bool page_attribute_table: 1;
|
||||||
bool global: 1;
|
bool global: 1;
|
||||||
uint8_t available_1 : 3;
|
uint8_t available_1 : 3;
|
||||||
uint32_t address : 20; // Multiply by 0x1000
|
uintptr_t address : 20; // Multiply by 0x1000
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
extern struct x86_Page_Directory boot_page_directory[1024] __attribute__((aligned(4096)));
|
extern struct x86_Page_Directory boot_page_directory[1024] __attribute__((aligned(4096)));
|
||||||
|
|
||||||
|
static struct x86_Page_Table user_code_table __attribute__((aligned(4096)));
|
||||||
|
static uint8_t user_code[4096] __attribute__((aligned(4096)));
|
||||||
|
|
||||||
|
static struct x86_Page_Table user_data_table __attribute__((aligned(4096)));
|
||||||
|
static uint8_t user_data[4096] __attribute__((aligned(4096)));
|
||||||
|
|
||||||
static struct x86_Page_Table* get_table(uint16_t index) {
|
static struct x86_Page_Table* get_table(uint16_t index) {
|
||||||
struct x86_Page_Table* table = (struct x86_Page_Table*)(boot_page_directory[index].address * 0x1000 + 0xC0000000);
|
struct x86_Page_Table* table = (struct x86_Page_Table*)((boot_page_directory[index].address << 12) + 0xC0000000);
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_paging() {
|
static void reload_pages () {
|
||||||
struct x86_Page_Table* kernel = get_table(768);
|
asm("\
|
||||||
for (int i = 0; i < 1024; i++) {
|
movl %cr3, %ecx; \
|
||||||
if (kernel[i].address != 0) {
|
movl %ecx, %cr3; \
|
||||||
struct x86_Page_Table test = kernel[i];
|
");
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_page_directory_entry(uintptr_t address, struct x86_Page_Table* table) {
|
||||||
|
boot_page_directory[address >> 22].address = ((uintptr_t)(table) - 0xC0000000) >> 12;
|
||||||
|
boot_page_directory[address >> 22].present = true;
|
||||||
|
boot_page_directory[address >> 22].read_write = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setup_paging() {
|
||||||
|
struct x86_Page_Table* kernel = get_table(768);
|
||||||
|
uint16_t i = 0;
|
||||||
|
while (kernel[i].present == 0) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
terminal_writestring("Kernel Start Page: ");
|
||||||
|
print_hex_bytes(&i, 2);
|
||||||
|
while (kernel[i].present != 0) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
terminal_writestring("\nKernel End Page: ");
|
||||||
|
print_hex_bytes(&i, 2);
|
||||||
|
terminal_putchar('\n');
|
||||||
|
|
||||||
|
set_page_directory_entry(0, &user_code_table);
|
||||||
|
|
||||||
|
user_code_table.address = ((uintptr_t)user_code - 0xC0000000) >> 12;
|
||||||
|
user_code_table.present = true;
|
||||||
|
user_code_table.read_write = true;
|
||||||
|
user_code_table.user_supervisor = true;
|
||||||
|
|
||||||
|
set_page_directory_entry(0x00400000, &user_data_table);
|
||||||
|
|
||||||
|
user_data_table.address = ((uintptr_t)user_data - 0xC0000000) >> 12;
|
||||||
|
user_data_table.present = true;
|
||||||
|
user_data_table.read_write = true;
|
||||||
|
user_data_table.user_supervisor = true;
|
||||||
|
|
||||||
|
reload_pages();
|
||||||
|
}
|
||||||
|
|
|
@ -19,14 +19,14 @@ extern void jump_to_userspace();
|
||||||
void run_program(uint8_t* code, size_t code_length, uint8_t* data, size_t data_length)
|
void run_program(uint8_t* code, size_t code_length, uint8_t* data, size_t data_length)
|
||||||
{
|
{
|
||||||
uint8_t* userland_code = (uint8_t*) 0x00000000;
|
uint8_t* userland_code = (uint8_t*) 0x00000000;
|
||||||
uint8_t* userland_data = (uint8_t*) 0x00800000;
|
uint8_t* userland_data = (uint8_t*) 0x00400000;
|
||||||
|
|
||||||
memcpy(userland_code, code, code_length);
|
memcpy(userland_code, code, code_length);
|
||||||
memcpy(userland_data, data, data_length);
|
memcpy(userland_data, data, data_length);
|
||||||
|
|
||||||
struct CPUState target = {
|
struct CPUState target = {
|
||||||
.eip = (size_t) userland_code,
|
.eip = (size_t) userland_code,
|
||||||
.esp = 0x00000000,
|
.esp = 0x00400000,
|
||||||
.eax = 0,
|
.eax = 0,
|
||||||
.ebx = 0,
|
.ebx = 0,
|
||||||
.ecx = 0,
|
.ecx = 0,
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <kernel/heap.h>
|
#include <kernel/heap.h>
|
||||||
#include <debugging.h>
|
#include <debugging.h>
|
||||||
|
|
||||||
#define HEAP_SIZE (4096)
|
#define HEAP_SIZE (1 << 12)
|
||||||
|
|
||||||
uint8_t* global_heap_data[HEAP_SIZE + sizeof(struct Heap_Block)];
|
uint8_t* global_heap_data[HEAP_SIZE + sizeof(struct Heap_Block)];
|
||||||
struct Heap_Metadata global_heap;
|
struct Heap_Metadata global_heap;
|
||||||
|
|
|
@ -14,13 +14,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t program[] = {
|
uint8_t program[] = {
|
||||||
// 0xba, 0x01, 0x00, 0x00, 0x00, // mov 1, %edx
|
|
||||||
0xb8, 0x00, 0x00, 0xC0, 0x00, // mov $buffer, %eax
|
|
||||||
// 0xcd, 0x80, // int 0x80
|
|
||||||
0xb9, 0x00, 0x00, 0x00, 0x00, // mov 0, %ecx
|
|
||||||
0xcd, 0x80, // int 0x80
|
0xcd, 0x80, // int 0x80
|
||||||
0xb9, 0x00, 0x00, 0x80, 0x00, // mov $start, %ecx
|
|
||||||
0xff, 0xe1, // jmp *%ecx
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t data[] = "Hello From Userspace\n";
|
uint8_t data[] = "Hello From Userspace\n";
|
||||||
|
@ -39,11 +33,14 @@ void kernel_main(void)
|
||||||
setup_tasks();
|
setup_tasks();
|
||||||
setup_paging();
|
setup_paging();
|
||||||
|
|
||||||
asm("sti");
|
asm("cli");
|
||||||
|
|
||||||
run_program(program, sizeof(program), data, sizeof(data));
|
run_program(program, sizeof(program), data, sizeof(data));
|
||||||
|
|
||||||
|
asm("sti");
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
terminal_writestring("Hello from Kernelspace\n");
|
terminal_writestring("Hello from Kernelspace 1\n");
|
||||||
|
terminal_writestring("Hello from Kernelspace 2\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ static void input(char* buffer)
|
||||||
|
|
||||||
void _syscall(uint32_t a, uint32_t b, uint32_t c)
|
void _syscall(uint32_t a, uint32_t b, uint32_t c)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
print((char*) a);
|
print((char*) a);
|
||||||
|
@ -33,4 +34,6 @@ void _syscall(uint32_t a, uint32_t b, uint32_t c)
|
||||||
input((char*) a);
|
input((char*) a);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
terminal_writestring("waow :3");
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ void _switch_task(
|
||||||
size_t ds_passed
|
size_t ds_passed
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
terminal_writestring("Switching task\n");
|
// terminal_writestring("Switching task\n");
|
||||||
if (num_tasks == 0) {
|
if (num_tasks == 0) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue