void init_task(struct Task_t *t, uint16_t cs, uint16_t ds, uint16_t ss) { memset(t, 0, sizeof(struct Task_t)); uint32_t page_dir_pn = alloc_phy_page(0, 1023); uint32_t stack; t->block_event = NONBLOCKED; t->page_dir = (uint32_t *)(page_dir_pn << 12); if(CURRENT_TASK) t->ppid = CURRENT_TASK->pid; else t->ppid = 7; map_kernel_page(page_dir_pn, page_dir_pn, true, false, true); memset(t->page_dir, 0, 4096); t->page_dir[0] = PAGE_DIR[0]; t->block_event = 0; t->next = NULL; t->status = READY; t->tss.cr3 = (uint32_t)t->page_dir; t->tss.eflags = 0x202; t->tss.cs = cs; t->tss.ds = ds; t->tss.es = ds; t->tss.fs = ds; t->tss.gs = ds; t->tss.ss = ss; t->sem_list_size = 0; t->sigint_handler = sigint_default; stack = alloc_phy_page(1024, max_page_num); map_page(t->page_dir, (0xFFFFFFFF - 4096 + 1) >> 12, stack, false, true, true); t->tss.esp = 0xFFFFFFFF; }
void *alloc_vm_stack(ulong size) { ulong phsize = 0; ulong addr; DEBUG_PRINT("Alloc vm stack:%lx\n", size); void *p = alloc_linear(size + PAGE_SIZE); //one more page if (!p) return p; addr = (ulong) p + PAGE_SIZE; //the lowest page is reserved for stack overflow check while (phsize <= size) { ulong pg = alloc_phy_page(); if (!pg) { if (phsize) { free_vm_page(addr, phsize); free_linear(addr, size); } return (void *)0; } map_page_p2v_rw(pg, addr); addr += PAGE_SIZE; phsize += PAGE_SIZE; } return (void *)((ulong) p + PAGE_SIZE); }
void map_page(uint32_t *page_dir, uint32_t virt_page_num, uint32_t phy_page_num, bool global, bool user, bool read_write) { uint16_t pd_idx = PD_IDX(virt_page_num), pt_idx = PT_IDX(virt_page_num); uint32_t *page_table; if(!(page_dir[pd_idx] & 0x1)) { uint32_t pt_page_num = alloc_phy_page(0, 1023); map_kernel_page(pt_page_num, pt_page_num, true, false, true); memset((void *)(pt_page_num << 12), 0, 4096); page_dir[pd_idx] = make_pde(pt_page_num, user, read_write); } page_table = (uint32_t *)(page_dir[pd_idx] & 0xfffff000); page_table[pt_idx] = make_pte(phy_page_num, global, user, read_write); ++phy_mem_rc[phy_page_num]; __asm__ volatile( ".intel_syntax noprefix;" "mov eax, cr3;" "mov cr3, eax;" ".att_syntax;" :::"eax" ); }
void *alloc_vm(ulong size) { ulong phsize = 0; ulong addr; DEBUG_PRINT("Alloc vm:%lx\n", size); void *p = alloc_linear(size); if (!p) return p; addr = (ulong) p; while (phsize <= size) { ulong pg = alloc_phy_page(); if (!pg) { if (phsize) { free_vm_page(addr, phsize); free_linear(addr, size); } return (void *)0; } map_page_p2v_rw(pg, addr); addr += PAGE_SIZE; phsize += PAGE_SIZE; } return p; }