task switch progress
This commit is contained in:
parent
1b7474095b
commit
5f025d18bf
2
bochsrc
2
bochsrc
|
@ -2,4 +2,4 @@ ata0-slave: type=cdrom, path=./build/Hazel.iso, status=inserted
|
||||||
magic_break: enabled=1
|
magic_break: enabled=1
|
||||||
boot: cdrom
|
boot: cdrom
|
||||||
|
|
||||||
display_library: x
|
display_library: sdl2
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <kernel/elf.h>
|
#include <kernel/elf.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t eip;
|
|
||||||
uint32_t esp;
|
uint32_t esp;
|
||||||
uint32_t cr3;
|
uint32_t cr3;
|
||||||
uint32_t *next;
|
uint32_t *next;
|
||||||
|
|
|
@ -118,22 +118,22 @@ flush_tss:
|
||||||
extern ctx
|
extern ctx
|
||||||
global task_switch
|
global task_switch
|
||||||
task_switch:
|
task_switch:
|
||||||
|
; Save current task's registers
|
||||||
push ebx
|
push ebx
|
||||||
push esi
|
push esi
|
||||||
push edi
|
push edi
|
||||||
push ebp
|
push ebp
|
||||||
|
|
||||||
mov esi, [ctx+28]
|
mov edi, [ctx+28] ; EDI = current task
|
||||||
; Return if only one process is running
|
mov esi, [esp+20] ; ESI = next task
|
||||||
mov eax, [esi+12]
|
; Save current ESP
|
||||||
cmp eax, 0
|
mov dword [edi], esp
|
||||||
je ret
|
; Set current task to next task
|
||||||
; Check if using same virtual memory
|
mov dword [ctx+28], esi
|
||||||
cmp [esi+8], [eax+8]
|
; Change to new ESP
|
||||||
je .ret
|
mov esp, [esi]
|
||||||
mov ecx, [eax+8]
|
mov ecx, [esi+4]
|
||||||
mov cr3, ecx
|
|
||||||
.ret:
|
|
||||||
pop ebp
|
pop ebp
|
||||||
pop edi
|
pop edi
|
||||||
pop esi
|
pop esi
|
||||||
|
|
|
@ -18,6 +18,7 @@ extern uint32_t isr_stub_table[32];
|
||||||
extern void pit_isr(void);
|
extern void pit_isr(void);
|
||||||
extern void jmp_user_mode(uint32_t esp, uint32_t eip);
|
extern void jmp_user_mode(uint32_t esp, uint32_t eip);
|
||||||
extern void flush_tss(uint32_t segment_selector);
|
extern void flush_tss(uint32_t segment_selector);
|
||||||
|
extern void task_switch(task_t *task);
|
||||||
extern gdt_t gdt[6];
|
extern gdt_t gdt[6];
|
||||||
extern uint32_t boot_page_dir[1024];
|
extern uint32_t boot_page_dir[1024];
|
||||||
extern uint32_t boot_page_tab[1024];
|
extern uint32_t boot_page_tab[1024];
|
||||||
|
@ -35,7 +36,7 @@ void sleep(int delay) {
|
||||||
cpu_relax;
|
cpu_relax;
|
||||||
}
|
}
|
||||||
|
|
||||||
void idt_init() {
|
void idt_init(void) {
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
idt_encode_entry(idt, i, isr_stub_table[i], GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), TRAP_GATE_32 | INT_RING0 | INT_PRESENT);
|
idt_encode_entry(idt, i, isr_stub_table[i], GDT_SEGMENT_SELECTOR(GDT_KERNEL_CODE, RING0), TRAP_GATE_32 | INT_RING0 | INT_PRESENT);
|
||||||
}
|
}
|
||||||
|
@ -47,6 +48,13 @@ void idt_init() {
|
||||||
asm volatile ("lidt %0" :: "m"(idtr));
|
asm volatile ("lidt %0" :: "m"(idtr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test(void) {
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
LOG("O");
|
||||||
|
}
|
||||||
|
task_switch((task_t *)ctx.current_task->next);
|
||||||
|
}
|
||||||
|
|
||||||
void kernel(multiboot_info_t *info) {
|
void kernel(multiboot_info_t *info) {
|
||||||
if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules
|
if (!CHECK_FLAG(info->flags, 3)) goto halt; // Modules
|
||||||
if (!CHECK_FLAG(info->flags, 6)) goto halt; // Memory map
|
if (!CHECK_FLAG(info->flags, 6)) goto halt; // Memory map
|
||||||
|
@ -61,14 +69,12 @@ void kernel(multiboot_info_t *info) {
|
||||||
LOG("%d bytes of RAM detected\nCreated a %d byte large physical memory map at 0x%08X\n", ctx.mmap_size*BLOCK_SIZE*8, ctx.mmap_size, (uint32_t)ctx.mmap);
|
LOG("%d bytes of RAM detected\nCreated a %d byte large physical memory map at 0x%08X\n", ctx.mmap_size*BLOCK_SIZE*8, ctx.mmap_size, (uint32_t)ctx.mmap);
|
||||||
|
|
||||||
idt_init();
|
idt_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pic_remap(PIC_1_START, PIC_2_START);
|
pic_remap(PIC_1_START, PIC_2_START);
|
||||||
asm volatile ("sti" ::);
|
asm volatile ("sti" ::);
|
||||||
ctx.ticks = 0;
|
ctx.ticks = 0;
|
||||||
pit_init();
|
pit_init();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Setup TSS
|
// Setup TSS
|
||||||
uint32_t base = (uint32_t)&tss;
|
uint32_t base = (uint32_t)&tss;
|
||||||
uint32_t limit = base + sizeof(tss_t);
|
uint32_t limit = base + sizeof(tss_t);
|
||||||
|
@ -87,6 +93,30 @@ void kernel(multiboot_info_t *info) {
|
||||||
tss.ss = tss.ds = tss.es = tss.fs = tss.gs = GDT_SEGMENT_SELECTOR(GDT_USER_DATA, RING3);
|
tss.ss = tss.ds = tss.es = tss.fs = tss.gs = GDT_SEGMENT_SELECTOR(GDT_USER_DATA, RING3);
|
||||||
flush_tss(GDT_SEGMENT_SELECTOR(5, RING3));
|
flush_tss(GDT_SEGMENT_SELECTOR(5, RING3));
|
||||||
|
|
||||||
|
task_t task1 = {0};
|
||||||
|
task_t task2 = {0};
|
||||||
|
task1.cr3 = (uint32_t)boot_page_dir - KERNEL_VMA;
|
||||||
|
task1.next = (uint32_t *)&task2;
|
||||||
|
ctx.current_task = &task1;
|
||||||
|
|
||||||
|
uint32_t *stack = mmap_find_first_free_block();
|
||||||
|
asm volatile ("mov %%esp, %0" : "=r" (task1.esp));
|
||||||
|
stack[1023] = (uint32_t)test;
|
||||||
|
stack[1022] = 0;
|
||||||
|
stack[1021] = 0;
|
||||||
|
stack[1020] = 0;
|
||||||
|
stack[1019] = 0;
|
||||||
|
task2.esp = (uint32_t)stack + (0x1000 - 20);
|
||||||
|
task2.cr3 = (uint32_t)boot_page_dir - KERNEL_VMA;
|
||||||
|
task2.next = (uint32_t *)&task1;
|
||||||
|
//task_switch(&task2);
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
LOG("_");
|
||||||
|
}
|
||||||
|
task_switch((task_t *)ctx.current_task->next);
|
||||||
|
task_switch((task_t *)ctx.current_task->next);
|
||||||
|
|
||||||
|
/*
|
||||||
multi_mod_t *init = (multi_mod_t *)(info->moduleaddress + KERNEL_VMA);
|
multi_mod_t *init = (multi_mod_t *)(info->moduleaddress + KERNEL_VMA);
|
||||||
elf_t *elf = (elf_t *)(init->mod_start+KERNEL_VMA);
|
elf_t *elf = (elf_t *)(init->mod_start+KERNEL_VMA);
|
||||||
task_t task = {0};
|
task_t task = {0};
|
||||||
|
@ -97,6 +127,7 @@ void kernel(multiboot_info_t *info) {
|
||||||
|
|
||||||
LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", task.eip, task.esp);
|
LOG("Switching to ring 3... EIP: 0x%08X ESP: 0x%08X\n", task.eip, task.esp);
|
||||||
jmp_user_mode(task.esp, task.eip);
|
jmp_user_mode(task.esp, task.eip);
|
||||||
|
*/
|
||||||
|
|
||||||
halt:
|
halt:
|
||||||
for (;;) {}
|
for (;;) {}
|
||||||
|
|
11
kernel/pit.c
11
kernel/pit.c
|
@ -12,9 +12,20 @@ void pit_init(void) {
|
||||||
outb(PIT_CHAN0_DATA, (uint8_t)((DIVISOR & 0xff00) >> 8));
|
outb(PIT_CHAN0_DATA, (uint8_t)((DIVISOR & 0xff00) >> 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void task_switch(task_t *task);
|
||||||
|
|
||||||
void pit_handler(void) {
|
void pit_handler(void) {
|
||||||
ctx.ticks++;
|
ctx.ticks++;
|
||||||
|
|
||||||
|
if (ctx.current_task->next) {
|
||||||
|
LOG("TASK SWITCH\n");
|
||||||
|
//task_t *old = ctx.current_task;
|
||||||
|
//task_t *new = (task_t *)ctx.current_task->next;
|
||||||
|
//new->next = (uint32_t *)old;
|
||||||
|
//old->next = (uint32_t *)new;
|
||||||
|
task_switch((task_t *)ctx.current_task->next);
|
||||||
|
}
|
||||||
|
|
||||||
outb(PIT_CHAN0_DATA, (uint8_t)(DIVISOR & 0xff));
|
outb(PIT_CHAN0_DATA, (uint8_t)(DIVISOR & 0xff));
|
||||||
outb(PIT_CHAN0_DATA, (uint8_t)((DIVISOR & 0xff00) >> 8));
|
outb(PIT_CHAN0_DATA, (uint8_t)((DIVISOR & 0xff00) >> 8));
|
||||||
pic_send_eoi(0);
|
pic_send_eoi(0);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user