Skip to content

Commit 9ed6b71

Browse files
committed
Interrupt Handling and Context Switching
- isr.c - Modified interrupt handler logic. - sched.c - Updated task switching for initial boot. - paging.c - Expanded kernel memory mapping. - interrupts.h - Corrected stack frame definition. - isr.s - Cleaned up interrupt return.
1 parent 32ba861 commit 9ed6b71

7 files changed

Lines changed: 66 additions & 33 deletions

File tree

include/interrupts.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "types.h"
55

66
typedef struct {
7-
uint32_t ds;
7+
uint32_t gs, fs, es, ds;
88
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
99
uint32_t int_no, err_code;
1010
uint32_t eip, cs, eflags, useresp, ss;

src/cpu/isr.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,6 @@ static void vga_write_hex32(uint32_t value, uint8_t color) {
6363
}
6464
}
6565

66-
static void vga_write_hex64(uint64_t value, uint8_t color) {
67-
static const char hex[] = "0123456789ABCDEF";
68-
vga_write_string("0x", color);
69-
for (int i = 15; i >= 0; --i) {
70-
uint8_t nibble = (uint8_t)((value >> (i * 4)) & 0xF);
71-
vga_put_char((uint8_t)hex[nibble], color);
72-
}
73-
}
74-
7566
static void vga_write_label_hex(const char* label, uint32_t value, uint8_t color) {
7667
vga_write_string(label, color);
7768
vga_write_hex32(value, color);
@@ -202,11 +193,14 @@ static registers_t* irq0_handler(registers_t* regs) {
202193
if (!previous || !next || next == previous) {
203194
return regs;
204195
}
196+
197+
previous->esp = (uint32_t)regs;
198+
205199
if (next->page_directory) {
206200
load_cr3(next->page_directory);
207201
}
208-
context_switch(previous, next, regs);
209-
return regs;
202+
203+
return (registers_t*)next->esp;
210204
}
211205

212206
void register_interrupt_handler(uint8_t n, isr_t handler) {
@@ -231,10 +225,11 @@ registers_t* isr_handler(registers_t* regs) {
231225
}
232226

233227
registers_t* irq_handler(registers_t* regs) {
234-
if (interrupt_handlers[regs->int_no]) {
235-
regs = interrupt_handlers[regs->int_no](regs);
228+
uint32_t int_no = regs->int_no;
229+
if (interrupt_handlers[int_no]) {
230+
regs = interrupt_handlers[int_no](regs);
236231
}
237-
if (regs->int_no >= 40) {
232+
if (int_no >= 40) {
238233
outb(0xA0, 0x20);
239234
}
240235
outb(0x20, 0x20);

src/cpu/isr.s

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ isr_common_stub:
111111

112112
popa
113113
add esp, 8
114-
sti
115114
iret
116115

117116
irq_common_stub:
@@ -145,5 +144,4 @@ irq_common_stub:
145144

146145
popa
147146
add esp, 8
148-
sti
149147
iret

src/kernel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,8 @@ void kernel_main(unsigned int multiboot_magic, unsigned int multiboot_info_addr)
388388
}
389389
}
390390

391-
paging_init();
392391
acpi_scan();
392+
paging_init();
393393
apex_intc_init();
394394
msgi_init();
395395
smp_rally_init();

src/kernel/sched.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -305,16 +305,8 @@ static process_t* process_create_ex(void (*entry)(void), uint32_t* page_director
305305
list_append(proc);
306306

307307
if (start_immediately) {
308-
process_t* current = scheduler_current();
309-
if (!current) {
310-
uint32_t cpu = get_cpu_id();
311-
current_process[cpu] = proc;
312-
proc->current_cpu = cpu;
313-
proc->state = PROCESS_RUNNING;
314-
} else {
315-
proc->state = PROCESS_READY;
316-
enqueue_task(proc);
317-
}
308+
proc->state = PROCESS_READY;
309+
enqueue_task(proc);
318310
}
319311

320312
spin_unlock(&sched_lock);
@@ -646,7 +638,23 @@ process_t* switch_task(registers_t* saved_stack, process_t** previous) {
646638
scheduler_wake_sleepers(now);
647639
scheduler_account_tick();
648640

649-
if (!current || !process_list) {
641+
if (!current) {
642+
process_t* best = scheduler_pick_best_ready();
643+
if (best) {
644+
dequeue_task(best);
645+
current_process[cpu] = best;
646+
best->state = PROCESS_RUNNING;
647+
best->time_remaining = best->time_slice;
648+
if (previous) *previous = 0;
649+
spin_unlock(&sched_lock);
650+
return best;
651+
}
652+
if (previous) *previous = 0;
653+
spin_unlock(&sched_lock);
654+
return 0;
655+
}
656+
657+
if (!process_list) {
650658
if (previous) *previous = current;
651659
spin_unlock(&sched_lock);
652660
return current;

src/mem/paging.c

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "paging.h"
22
#include "heap.h"
3+
#include "kernel.h"
34
#include "pmm.h"
45
#include "types.h"
56
#include "util.h"
@@ -112,11 +113,35 @@ void paging_init(void) {
112113
page_directory[i] = PAGE_RW;
113114
}
114115

115-
uint32_t* first_table = alloc_table();
116-
for (uint32_t i = 0; i < 1024; ++i) {
117-
first_table[i] = (i * 0x1000) | PAGE_PRESENT | PAGE_RW;
116+
for (uint32_t t = 0; t < 4; ++t) {
117+
uint32_t* table = alloc_table();
118+
for (uint32_t i = 0; i < 1024; ++i) {
119+
table[i] = (t * 0x400000 + i * 0x1000) | PAGE_PRESENT | PAGE_RW;
120+
}
121+
page_directory[t] = ((uint32_t)table) | PAGE_PRESENT | PAGE_RW;
122+
}
123+
124+
// Identity map LAPIC and IOAPIC regions (0xFE000000 - 0xFFFFFFFF)
125+
// We use 4MB pages for simplicity since PSE is enabled
126+
map_page_4mb(0xFEC00000, 0xFEC00000, PAGE_PRESENT | PAGE_RW);
127+
map_page_4mb(0xFF000000, 0xFF000000, PAGE_PRESENT | PAGE_RW);
128+
129+
// Identity map ACPI tables
130+
uint32_t rsdt = acpi_rsdt_addr();
131+
if (rsdt) {
132+
for (uint32_t i = 0; i < 4; i++) {
133+
map_page(rsdt + i * 4096, rsdt + i * 4096, PAGE_PRESENT | PAGE_RW);
134+
}
135+
uint32_t count = acpi_rsdt_entries();
136+
for (uint32_t i = 0; i < count; i++) {
137+
uint32_t entry = acpi_rsdt_entry(i);
138+
if (entry) {
139+
for (uint32_t j = 0; j < 4; j++) {
140+
map_page(entry + j * 4096, entry + j * 4096, PAGE_PRESENT | PAGE_RW);
141+
}
142+
}
143+
}
118144
}
119-
page_directory[0] = ((uint32_t)first_table) | PAGE_PRESENT | PAGE_RW;
120145

121146
load_cr3(page_directory);
122147
enable_pse();

src/video/framebuffer.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "framebuffer.h"
2+
#include "paging.h"
23
#include "vga.h"
34
#include "font.h"
45
#include "multiboot.h"
@@ -157,6 +158,12 @@ void fb_init(void* multiboot_info) {
157158
framebuffer.pitch = mode->pitch;
158159
framebuffer.bpp = mode->bpp;
159160
framebuffer.type = FB_TYPE_LINEAR;
161+
162+
// Map the framebuffer memory
163+
uint32_t fb_size = framebuffer.height * framebuffer.pitch;
164+
for (uint32_t i = 0; i < fb_size; i += 4 * 1024 * 1024) {
165+
map_page_4mb((uint32_t)framebuffer.address + i, (uint32_t)framebuffer.address + i, 0x03); // Present | RW
166+
}
160167
}
161168
}
162169
}

0 commit comments

Comments
 (0)