aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/core')
-rw-r--r--src/kernel/core/context_switch.s35
-rw-r--r--src/kernel/core/dbglog.c7
-rw-r--r--src/kernel/core/kmain.c6
-rw-r--r--src/kernel/core/paging.c36
-rw-r--r--src/kernel/core/thread.c6
5 files changed, 33 insertions, 57 deletions
diff --git a/src/kernel/core/context_switch.s b/src/kernel/core/context_switch.s
index 6738a03..b8f6bb8 100644
--- a/src/kernel/core/context_switch.s
+++ b/src/kernel/core/context_switch.s
@@ -4,11 +4,10 @@
[GLOBAL save_context_and_enter_scheduler]
; void save_context_and_enter_scheduler(struct saved_context *ctx);
save_context_and_enter_scheduler:
- pushf
+ pushf ; push flags
cli
- pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
-
- mov eax, cr3
+ pusha ; push general registers
+ mov eax, cr3 ; push CR3
push eax
mov eax, [esp+44] ; get address of saved_context structure
@@ -19,32 +18,10 @@ save_context_and_enter_scheduler:
jmp run_scheduler
resume_saved_context:
- pop eax
- mov cr3, eax
-
- popa
- popf
- ret
-
-[GLOBAL irq0_save_context_and_enter_scheduler]
-; meant to be called on IRQ0
-; general registers already saved by IRQ handler stub
-; flags already saved by interruption and interruptions disabled
-; only saves CR3
-irq0_save_context_and_enter_scheduler:
- mov eax, cr3
- push eax
-
- mov eax, [esp+8] ; get address of saved_context structure
- mov [eax], esp ; save esp
- mov dword [eax+4], resume_saved_irq0_context ; save eip
-
- mov esp, kernel_stack_top
- jmp run_scheduler
-
-resume_saved_irq0_context:
- pop eax
+ pop eax ; restore CR3
mov cr3, eax
+ popa ; restore general registers
+ popf ; restore flags
ret
diff --git a/src/kernel/core/dbglog.c b/src/kernel/core/dbglog.c
index e042625..54d396c 100644
--- a/src/kernel/core/dbglog.c
+++ b/src/kernel/core/dbglog.c
@@ -14,9 +14,9 @@
static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;
-static uint8_t vga_color = 7;
-static uint16_t* vga_buffer = 0;
-static uint16_t vga_row = 0, vga_column = 0;
+static uint8_t vga_color;
+static uint16_t* vga_buffer;
+static uint16_t vga_row, vga_column;
static uint16_t make_vgaentry(char c, uint8_t color) {
uint16_t c16 = c;
@@ -41,6 +41,7 @@ static void vga_init() {
vga_row = 0;
vga_column = 0;
vga_buffer = (uint16_t*) (K_HIGHHALF_ADDR + 0xB8000);
+ vga_color = 7;
for (size_t y = 0; y < VGA_HEIGHT; y++) {
for (size_t x = 0; x < VGA_WIDTH; x++) {
diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c
index f5d2ace..9b9a050 100644
--- a/src/kernel/core/kmain.c
+++ b/src/kernel/core/kmain.c
@@ -95,13 +95,15 @@ void kmain(multiboot_info_t *mbd, int32_t mb_magic) {
dbg_printf("Paging seems to be working!\n");
region_allocator_init(kernel_data_end);
-
+ dbg_printf("Region allocator initialized.\n");
TEST_PLACEHOLDER_AFTER_REGION;
kmalloc_setup();
+ dbg_printf("Kernel malloc setup ok.\n");
TEST_PLACEHOLDER_AFTER_KMALLOC;
setup_syscalls();
+ dbg_printf("System calls setup ok.\n");
// enter multi-threading mode
// interrupts are enabled at this moment, so all
@@ -111,6 +113,8 @@ void kmain(multiboot_info_t *mbd, int32_t mb_magic) {
}
void kernel_init_stage2(void* data) {
+ dbg_printf("Threading setup ok.\n");
+
multiboot_info_t *mbd = (multiboot_info_t*)data;
dbg_print_region_info();
diff --git a/src/kernel/core/paging.c b/src/kernel/core/paging.c
index 5a58c8c..69fb98f 100644
--- a/src/kernel/core/paging.c
+++ b/src/kernel/core/paging.c
@@ -10,17 +10,6 @@
#define PAGE_OF_ADDR(x) (((size_t)x >> PAGE_SHIFT) % N_PAGES_IN_PT)
#define PT_OF_ADDR(x) ((size_t)x >> (PAGE_SHIFT + PT_SHIFT))
-#define PTE_PRESENT (1<<0)
-#define PTE_RW (1<<1)
-#define PTE_USER (1<<2)
-#define PTE_WRITE_THROUGH (1<<3)
-#define PTE_DISABLE_CACHE (1<<4)
-#define PTE_ACCESSED (1<<5)
-#define PTE_DIRTY (1<<6) // only PTE
-#define PTE_SIZE_4M (1<<7) // only PDE
-#define PTE_GLOBAL (1<<8) // only PTE
-#define PTE_FRAME_SHIFT 12
-
typedef struct page_table {
uint32_t page[1024];
} pagetable_t;
@@ -107,7 +96,7 @@ void page_fault_handler(registers_t *regs) {
if ((size_t)vaddr >= PD_MIRROR_ADDR) {
dbg_printf("Fault on access to mirrorred PD at 0x%p\n", vaddr);
- dbg_print_region_info();
+ dbg_dump_registers(regs);
PANIC("Unhandled kernel space page fault");
}
@@ -164,10 +153,11 @@ void paging_setup(void* kernel_data_end) {
// paging already enabled in loader, nothing to do.
- // disable 4M pages (remove PSE bit in CR4)
+
uint32_t cr4;
asm volatile("movl %%cr4, %0": "=r"(cr4));
- cr4 &= ~0x00000010;
+ cr4 &= ~(1<<4); // disable 4M pages (remove PSE bit in CR4)
+ cr4 |= (1<<7); // enable global PTE/PDE
asm volatile("movl %0, %%cr4":: "r"(cr4));
idt_set_ex_handler(EX_PAGE_FAULT, page_fault_handler);
@@ -191,15 +181,19 @@ void switch_pagedir(pagedir_t *pd) {
// Mapping and unmapping of pages //
// ============================== //
-uint32_t pd_get_frame(void* vaddr) {
+uint32_t pd_get_entry(void* vaddr) {
uint32_t pt = PT_OF_ADDR(vaddr);
uint32_t page = PAGE_OF_ADDR(vaddr);
pagetable_t *pd = ((size_t)vaddr >= K_HIGHHALF_ADDR ? &kernel_pd : current_pd);
- if (!pd->page[pt] & PTE_PRESENT) return 0;
- if (!current_pt[pt].page[page] & PTE_PRESENT) return 0;
- return current_pt[pt].page[page] >> PTE_FRAME_SHIFT;
+ if (!(pd->page[pt] & PTE_PRESENT)) return 0;
+ if (!(current_pt[pt].page[page] & PTE_PRESENT)) return 0;
+ return current_pt[pt].page[page];
+}
+
+uint32_t pd_get_frame(void* vaddr) {
+ return pd_get_entry(vaddr) >> PTE_FRAME_SHIFT;
}
bool pd_map_page(void* vaddr, uint32_t frame_id, bool rw) {
@@ -213,7 +207,7 @@ bool pd_map_page(void* vaddr, uint32_t frame_id, bool rw) {
pagetable_t *pd = ((size_t)vaddr >= K_HIGHHALF_ADDR ? &kernel_pd : current_pd);
mutex_lock(&pdd->mutex);
- if (!pd->page[pt] & PTE_PRESENT) {
+ if (!(pd->page[pt] & PTE_PRESENT)) {
uint32_t new_pt_frame = frame_alloc(1);
if (new_pt_frame == 0) {
mutex_unlock(&pdd->mutex);
@@ -243,8 +237,8 @@ void pd_unmap_page(void* vaddr) {
pagetable_t *pd = ((size_t)vaddr >= K_HIGHHALF_ADDR ? &kernel_pd : current_pd);
// no need to lock the PD's mutex
- if (!pd->page[pt] & PTE_PRESENT) return;
- if (!current_pt[pt].page[page] & PTE_PRESENT) return;
+ if (!(pd->page[pt] & PTE_PRESENT)) return;
+ if (!(current_pt[pt].page[page] & PTE_PRESENT)) return;
current_pt[pt].page[page] = 0;
invlpg(vaddr);
diff --git a/src/kernel/core/thread.c b/src/kernel/core/thread.c
index cc39eb2..e62b5a8 100644
--- a/src/kernel/core/thread.c
+++ b/src/kernel/core/thread.c
@@ -8,7 +8,6 @@
#include <paging.h>
void save_context_and_enter_scheduler(saved_context_t *ctx);
-void irq0_save_context_and_enter_scheduler(saved_context_t *ctx);
void resume_context(saved_context_t *ctx);
thread_t *current_thread = 0;
@@ -156,8 +155,9 @@ thread_t *new_thread(entry_t entry, void* data) {
// ========== //
static void irq0_handler(registers_t *regs) {
- if (current_thread != 0)
- irq0_save_context_and_enter_scheduler(&current_thread->ctx);
+ if (current_thread != 0) {
+ save_context_and_enter_scheduler(&current_thread->ctx);
+ }
}
void threading_setup(entry_t cont, void* arg) {
set_pit_frequency(TASK_SWITCH_FREQUENCY);