void install_tss(ULONG idx, UWORD kernelSS, UWORD kernelESP) { kprintf("TSS", "Installing TSS\n"); // install TSS descriptor ULONG base = (ULONG)&TSS; // install descriptor gdt_set_descriptor(idx, base, base + sizeof(struct tss_entry), I86_GDT_DESC_ACCESS | I86_GDT_DESC_EXEC_CODE | I86_GDT_DESC_DPL | I86_GDT_DESC_MEMORY, 0); // initialize TSS memset((void*)&TSS, 0, sizeof(struct tss_entry)); // set stack and segments TSS.ss0 = kernelSS; TSS.esp0 = kernelESP; TSS.cs = 0x0b; TSS.ss = 0x13; TSS.es = 0x13; TSS.ds = 0x13; TSS.fs = 0x13; TSS.gs = 0x13; // flush tss flush_tss(idx * sizeof(struct gdt_descriptor)); }
void init_gdt() { gdt_desc.limit = (sizeof(struct s_gdt_entry) * 6) - 1; gdt_desc.base = (unsigned int)&gdt; /* Null segment */ init_segment(0, 0, 0, 0, 0); /*Ring 0*/ /* Code segment */ init_segment(1, BASE, LIMIT, 0xC, 0x9A); /* Data segment */ init_segment(2, BASE, LIMIT, 0xC, 0x92); /*Ring 3*/ /* Code segment */ init_segment(3, BASE, LIMIT, 0xC, 0xFA); /* Data segment */ init_segment(4, BASE, LIMIT, 0xC, 0xF2); /*TSS*/ write_tss(5, 0x10, 0); flush_gdt(); flush_tss(); }
void install_tss (uint32_t idx, uint16_t kernelSS, uint16_t kernelESP) { //! install TSS descriptor uint32_t base = (uint32_t) &TSS; //! install descriptor gdt_set_descriptor (idx, base, base + sizeof (tss_entry), I86_GDT_DESC_ACCESS|I86_GDT_DESC_EXEC_CODE|I86_GDT_DESC_DPL|I86_GDT_DESC_MEMORY, 0); //! initialize TSS memset ((void*) &TSS, 0, sizeof (tss_entry)); //! set stack and segments TSS.ss0 = kernelSS; TSS.esp0 = kernelESP; TSS.cs=0x0b; TSS.ss = 0x13; TSS.es = 0x13; TSS.ds = 0x13; TSS.fs = 0x13; TSS.gs = 0x13; //! flush tss flush_tss (idx * sizeof (gdt_descriptor)); }
void sched_initialize() { list_head.prev = &list_head; list_head.next = &list_head; flush_tss(); pic_register_isr(IRQ0, sched_timer); }
void scheduler() { for (;;) { struct process *proc = current_proc ? current_proc->next : list_head.next; /* Find a runnable process */ while (proc == &list_head || proc->state != PROC_STATE_RUNNING) { if (proc != &list_head && proc->state == PROC_STATE_DEAD) { /* Release the dead process */ struct process *dead = proc; proc = proc->next; sched_remove(dead); proc_free(dead); } else { proc = proc->next; } } close_int(); current_proc = proc; /* Update TSS */ tss.ss0 = KERNEL_DATA_SELECTOR; tss.esp0 = proc->kernel_stack; flush_tss(); /* Change to process virtual address space */ set_cr3(CAST_VIRTUAL_TO_PHYSICAL(proc->page_dir)); if (!proc->context) init_context(proc); switch_kcontext(&sched_context, proc->context); /* Call schedule task */ if (sched_task) { sched_task(current_proc); sched_task = NULL; } } }
void install_tss() { uint32_t base = (uint32_t) &tss; gdt_set_entry(5, base, base + sizeof(tss_t), 0xE9); memset((void *) base, 0, sizeof(tss_t)); tss.esp0 = 0; tss.ss0 = 0x10; tss.cs = 0x0B; tss.ss = 0x13; tss.es = 0x13; tss.ds = 0x13; tss.fs = 0x13; tss.gs = 0x13; flush_tss(); }
static void init_gdt(){ gdt_ptr.limit = (sizeof(gdt_entry_t) * 7) - 1; gdt_ptr.base = (unsigned int) &gdt_entries; gdt_set_gate(0, 0, 0, 0, 0); gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); write_tss(5, 0x10, stack_hold); gdt_set_gate(6, 0, 0xFFFFF, 0x92, 0x0); gdt_set_gate(7, 0, 0xFFFFF, 0x9A, 0x0); gdt_flush((unsigned int) &gdt_ptr); flush_tss(); }