void init_gdt() { //Sets up the gdt pointer gdtp.limit = (sizeof(struct gdt_entry)*GDT_LEN)-1; gdtp.base = (unsigned int)&gdt_table; /*the first NULL entry*/ gdt_set_gate(0, 0,0,0,0); // 0x9A, 0x92, 0xFA, 0xF2 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); // Ok, add the tss set_tss(5, 0x10, 0x0); /*actually flushes gdt with lgdt code*/ gdt_flush((unsigned int)&gdtp); // now flush the TSS tss_flush(); }
void init_segment(void) { memset(gdt, 0, sizeof(gdt)); set_segment(&gdt[SEG_KERNEL_CODE], DPL_KERNEL, SEG_EXECUTABLE | SEG_READABLE); set_segment(&gdt[SEG_KERNEL_DATA], DPL_KERNEL, SEG_WRITABLE ); set_segment(&gdt[SEG_USER_CODE], DPL_USER, SEG_EXECUTABLE | SEG_READABLE); set_segment(&gdt[SEG_USER_DATA], DPL_USER, SEG_WRITABLE ); write_gdtr(gdt, sizeof(gdt)); set_tss(&gdt[SEG_TSS]); write_tr( SELECTOR_USER(SEG_TSS) ); }
void init_sched (void) { unsigned long eflags; eflags = read_flags (); if ((idle_task = kmalloc (sizeof (Task), 0)) == NULL) { printk ("init_sched: not enough memory\n"); write_flags (eflags); return; } idle_task->pid = next_pid++; idle_task->next = idle_task; #if 0 idle_task->kernel_stack = kstack; #endif idle_task->tss.link = 0; idle_task->tss.esp0 = (unsigned long) &kstack[PAGE_SIZE >> 2]; idle_task->tss.ss0 = KERNEL_DS; idle_task->tss.cr3 = (unsigned long) &pg_dir[0]; idle_task->tss.es = KERNEL_DS; idle_task->tss.cs = KERNEL_CS; idle_task->tss.ss = KERNEL_DS; idle_task->tss.ds = KERNEL_DS; idle_task->tss.fs = KERNEL_DS; idle_task->tss.gs = KERNEL_DS; current = idle_task; set_tss (idle_task); write_tr (idle_task->tss.tr); cli (); register_interrupt (0x08, do_timer); register_interrupt (0x80, do_fork); outb(0x36,0x43); outb(0xa9,0x40); outb(0x04,0x40); write_flags (eflags); }
static inline void flush_tss() { uint32_t base = (uint32_t)&tss; gdt_install_tss(base, base + sizeof(tss)); set_tss(TSS_SELECTOR); }