Example #1
0
int kernel_start()
{
	int i;

	// point to low address (0GB ~ ...)
	pgd_tmp[PGD_INDEX(0)] =
		(uint32_t)pte_low | PAGE_PRESENT | PAGE_WRITE;

	// point to high address (3GB ~ 4GB)
	pgd_tmp[PGD_INDEX(PAGE_OFFSET)] =
		(uint32_t)pte_hig | PAGE_PRESENT | PAGE_WRITE;

	for (i = 0; i < 1024; i++) {
		pte_low[i] = (i << 12) | PAGE_PRESENT | PAGE_WRITE;
	}

	for (i = 0; i < 1024; i++) {
		pte_hig[i] = (i << 12) | PAGE_PRESENT | PAGE_WRITE;
	}

	// set page directory
	set_cr3(pgd_tmp);
	page_on();

	kernel_stack_top = ((uint32_t)kernel_stack + STACK_SIZE) & 0xFFFFFFF0;

	set_esp(kernel_stack_top);

	global_mboot_ptr = 
		(multiboot_t *)((uint32_t)global_mboot_tmp + PAGE_OFFSET);

	kernel_init();

	return 0;
}
Example #2
0
void map(pgd_t *pgd_now, uint32_t va, uint32_t pa, uint32_t flags)
{       
        uint32_t pgd_idx = PGD_INDEX(va);
        uint32_t pte_idx = PTE_INDEX(va); 
        
        pte_t *pte = (pte_t *)(pgd_now[pgd_idx] & PAGE_MASK);
        if (!pte) {
                pte = (pte_t *)alloc_pages(1);
                pgd_now[pgd_idx] = (uint32_t)pte | PAGE_PRESENT | PAGE_WRITE;
                pte = (pte_t *)pa_to_ka(pte);
        } else {
                pte = (pte_t *)pa_to_ka(pte);
        }

        pte[pte_idx] = (pa & PAGE_MASK) | flags;

        tlb_reload_page(va);
}
Example #3
0
void unmap(pgd_t *pgd_now, uint32_t va)
{
        uint32_t pgd_idx = PGD_INDEX(va);
        uint32_t pte_idx = PTE_INDEX(va);

        pte_t *pte = (pte_t *)(pgd_now[pgd_idx] & PAGE_MASK);

        if (!pte) {
                return;
        }

        // 转换到内核线性地址
        pte = (pte_t *)(pa_to_ka(pte));

        pte[pte_idx] = 0;
        
        tlb_reload_page(va);
}
Example #4
0
uint32_t get_mapping(pgd_t *pgd_now, uint32_t va, uint32_t *pa)
{
        uint32_t pgd_idx = PGD_INDEX(va);
        uint32_t pte_idx = PTE_INDEX(va);

        pte_t *pte = (pte_t *)(pgd_now[pgd_idx] & PAGE_MASK);
        if (!pte) {
              return 0;
        }
        
        // 转换到内核线性地址
        pte = (pte_t *)(pa_to_ka(pte));

        // 如果地址有效而且指针不为NULL,则返回地址
        if (pte[pte_idx] != 0 && pa) {
                 *pa = pte[pte_idx] & PAGE_MASK;
                return 1;
        }

        return 0;
}
Example #5
0
void vmm_init(void)
{
        // 注册页错误中断的处理函数 
        register_interrupt_handler(INT_PAGE_FAULT, &do_page_fault);
        
        // 页表数组指针
        pte_t (*pte_kern)[PTE_SIZE] = (pte_t (*)[PTE_SIZE])pte_addr;

        // 构造页目录(MMU需要的是物理地址,此处需要减去偏移)
        uint32_t pgd_idx = PGD_INDEX(PAGE_OFFSET);
        for (uint32_t i = pgd_idx; i < pgd_idx + PTE_COUNT; ++i) {
                pgd_kern[i] = ((uint32_t)ka_to_pa(pte_kern[i])) | PAGE_PRESENT | PAGE_WRITE;
        }

        // 构造页表映射,内核 0xC0000000~0xF8000000 映射到 物理 0x00000000~0x38000000 (物理内存前896MB)
        uint32_t *pte_start = (uint32_t *)(pte_addr + PTE_SIZE * pgd_idx);
        for (uint32_t i = 0; i < PTE_SIZE * PTE_COUNT; ++i) {
                pte_start[i] = (i << 12) | PAGE_PRESENT | PAGE_WRITE;
        }

        switch_pgd((uint32_t)ka_to_pa(pgd_kern));
}