/** * Install the GDT. * Set both code and data base address 0, limit 4GB. */ void install_gdt() { _gdtr.limit = sizeof(union gdt_desc) * MAX_DESCRIPTORS; _gdtr.base = (uint32_t) _gdt; // null descriptor. set_gdt_desc(0, 0, 0, 0, 0); // code descriptor. set_gdt_desc(1, 0, 0xffffffff, 0b10011010, 0b11001111); // data descriptor. set_gdt_desc(2, 0, 0xffffffff, 0b10010010, 0b11001111); __asm__ volatile ("lgdt _gdtr"); }
void gdt_install(){ // null desc set_gdt_desc(0, 0, 0, 0, 0); // code descriptor, full 4 gigs and 4 kilobyte granularity set_gdt_desc(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // data descriptor, same as above set_gdt_desc(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // user code and data descriptors set_gdt_desc(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); set_gdt_desc(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // flush the gdt into memory flush_gdt(); }
int do_fork(unsigned int esp) { struct task_struct *tsk; struct regs *reg = (struct regs *)(esp + 4); int pid; DbgPrint("cs: 0x%x, eip: 0x%x, ds: 0x%x, eax: 0x%x, ebx: 0x%x\n" "ecx: 0x%x, es: 0x%x, fs: 0x%x, eflags: 0x%x\n" "ss: 0x%x, esp: 0x%x, orig_eax: 0x%x\n", reg->orig_cs, reg->orig_eip, reg->ds, reg->eax, reg->ebx, reg->ecx, reg->es, reg->fs, reg->eflags, reg->ss, reg->esp, reg->error_code); pid = get_pid(); if (pid == -1) { printk("Get new pid failed.\n"); return -1; } DbgPrint("Get new pid: %d\n", pid); tsk = (struct task_struct *)alloc_page(0); if (!tsk) { DbgPrint("Alloc tsk page failed.\n"); return -1; } printk("Alloc task_struct page at: 0x%x\n", tsk); *tsk = *current; tsk->tss.prev_task_link = 0; tsk->tss.esp0 = (unsigned int)tsk + PAGE_SIZE - 4; tsk->tss.ss0 = KERNEL_DATA_SEL; tsk->tss.esp1 = 0; tsk->tss.ss1 = 0; tsk->tss.esp2 = 0; tsk->tss.ss2 = 0; tsk->tss.eip = reg->orig_eip; tsk->tss.eflags = reg->eflags; tsk->tss.eax = 0; tsk->tss.ebx = reg->ebx; tsk->tss.ecx = reg->ecx; tsk->tss.edx = reg->edx; tsk->tss.esp = reg->esp; tsk->tss.ebp = reg->ebp; tsk->tss.esi = reg->esi; tsk->tss.edi = reg->edi; tsk->tss.es = reg->es; tsk->tss.cs = reg->orig_cs; tsk->tss.ss = reg->ss; tsk->tss.ds = reg->ds; tsk->tss.fs = reg->fs; tsk->tss.gs = USER_DATA_SEL; tsk->tss.ldt_sel = LDT_SEL(pid); tsk->tss.io_map = 0x80000000; tsk->pid = pid; tsk->tss_sel = TSS_SEL(pid); tsk->ldt_sel = LDT_SEL(pid); tsk->state = TASK_RUNABLE; tsk->counter = DEFAULT_COUNTER; tsk->priority = DEFAULT_PRIORITY; set_tss_desc(new_gdt, (unsigned int)&(tsk->tss), TSS_LIMIT, TSS_TYPE, TSS_IDX(pid)); set_ldt_desc(new_gdt, (unsigned int)&(tsk->ldt), LDT_LIMIT, LDT_TYPE, LDT_IDX(pid)); set_gdt_desc(tsk->ldt, CODE_BASE, USER_CODE_LIMIT, USER_CODE_TYPE, 1); set_gdt_desc(tsk->ldt, DATA_BASE, USER_DATA_LIMIT, USER_DATA_TYPE, 2); //setup_task_pages(tsk); copy_page_tables(tsk); list_add_tail(&(tsk->list), &task_list_head); /* printk("cs: 0x%x, eip: 0x%x, ds: 0x%x, eax: 0x%x, ebx: 0x%x\n" "ecx: 0x%x, es: 0x%x, fs: 0x%x, eflags: 0x%x\n" "ss: 0x%x, esp: 0x%x\n", tsk->tss.cs, tsk->tss.eip, tsk->tss.ds, tsk->tss.eax, tsk->tss.ebx, tsk->tss.ecx, tsk->tss.es, tsk->tss.fs, tsk->tss.eflags, tsk->tss.ss, tsk->tss.esp); */ printk("task esp0: 0x%x, esp: 0x%x\n", tsk->tss.esp0, tsk->tss.esp); return pid; }
int sys_creat_task(unsigned int eip) { struct task_struct *tsk; int pid; pid = get_pid(); if (pid == -1) { DbgPrint("Get pid failed.\n"); return -1; } printk("Get new pid: %d\n", pid); tsk = (struct task_struct *)alloc_page(0); if (!tsk) { DbgPrint("Alloc tsk page failed.\n"); return -1; } DbgPrint("Alloc tsk page at: 0x%x\n", tsk); *tsk = *current; tsk->tss.prev_task_link = 0; tsk->tss.esp0 = (unsigned int)tsk + PAGE_SIZE; tsk->tss.ss0 = KERNEL_DATA_SEL; tsk->tss.esp1 = 0; tsk->tss.ss1 = 0; tsk->tss.esp2 = 0; tsk->tss.ss2 = 0; tsk->tss.eip = eip; tsk->tss.eflags = 0x200; tsk->tss.eax = 0; tsk->tss.ebx = 0; tsk->tss.ecx = 0; tsk->tss.edx = 0; tsk->tss.esp = (unsigned int)alloc_page(0) + PAGE_SIZE; DbgPrint("Alloc tsk ring3 stack at 0x%x\n", tsk->tss.esp - PAGE_SIZE); tsk->tss.ebp = 0; tsk->tss.esi = 0; tsk->tss.edi = 0; tsk->tss.es = USER_DATA_SEL; tsk->tss.cs = USER_CODE_SEL; tsk->tss.ss = USER_DATA_SEL; tsk->tss.ds = USER_DATA_SEL; tsk->tss.fs = USER_DATA_SEL; tsk->tss.gs = USER_DATA_SEL; tsk->tss.ldt_sel = LDT_SEL(pid); tsk->tss.io_map = 0x80000000; tsk->pid = pid; tsk->tss_sel = TSS_SEL(pid); tsk->ldt_sel = LDT_SEL(pid); tsk->state = TASK_RUNABLE; tsk->counter = DEFAULT_COUNTER; tsk->priority = DEFAULT_PRIORITY; set_tss_desc(new_gdt, (unsigned int)&(tsk->tss), TSS_LIMIT, TSS_TYPE, TSS_IDX(pid)); set_ldt_desc(new_gdt, (unsigned int)&(tsk->ldt), LDT_LIMIT, LDT_TYPE, LDT_IDX(pid)); set_gdt_desc(tsk->ldt, CODE_BASE, USER_CODE_LIMIT, USER_CODE_TYPE, 1); set_gdt_desc(tsk->ldt, DATA_BASE, USER_DATA_LIMIT, USER_DATA_TYPE, 2); setup_task_pages(tsk); //copy_page_tables(tsk); list_add_tail(&(tsk->list), &task_list_head); return 0; }