my OS reboots when it enables paging
Posted: Mon Jan 11, 2016 9:40 am
I'm making an OS. and I made the code that enables paging.
before enabling paging, it initilizes page directory and page table
I cannot found what wrong is/
below is my paging source code.(sorry, the annotations are korean..)
and I uploaded the entire source code.
help me!
before enabling paging, it initilizes page directory and page table
I cannot found what wrong is/
below is my paging source code.(sorry, the annotations are korean..)
Code: Select all
---- /Kernel/Sources/mm/page.c ----
/*
Author : Hygon
Date : 2016-01-07
Last Edited Date :
참고 문헌 : http://wiki.osdev.org/Tutorials#Memory_Management
memo : 디렉터리를 not present 로 설정했는데
필요 할 때마다 present 로 변경되는 코드를 넣어야 한다.
그걸 고치고 나도 오류가 나면 원인을 더 찾아보자..
*페이지 디렉터리(4b*1024) + 페이지 테이블 (4b*1024*1024)의 여유공간 필요
*/
#include "../include/lib/stdio.h"
#include "../include/types.h"
#include "../include/mm/page.h"
int init_image_area()
{
//이미지 크기를 불러온 후에 이미지 만큼의 크기는 실제 물리 공간에 연결
//0~5M 4kb까지 연결 5M 4KB / 4KB - 1 을 인덱스로 해서 매핑
for(int i, addr = 0; i < 1280; i++){ //1024*1024(Image & Stack) + 4096(pgd) + 4096*1024(pmd) - 1 = 1280
mmap(addr, addr, 3);
addr+=4096;
}
return 1;
}
void init_pgd()
{
pgd_t *page_dir = (unsigned int *) PGD_ADDRESS; // 0x100000 부터 시작
unsigned int pmd_addr = PGD_ADDRESS + 1024;
for(int i = 0; i < 1024; i++){ // 엔트리 1024개 설정
page_dir[i] = pmd_addr | PGE_DEFAULT;
pmd_addr += 4096;
//Present : 0, Read/Write
}
}
void init_pmd()
{
pmd_t **page_table = (pmd_t **)PGD_ADDRESS + 1024;
unsigned int pte_addr = 0;
pte_addr = 0;
for(int i = 0; i < 1024; i++){
for(int i2=0; i2 < 1024; i2++){
page_table[i][i2] = pte_addr | PTE_DEFAULT;
//위의 비트 OR 연산이 이해가 가지 않는경우 직접 2진수로 변환해보길 바란다.
pte_addr += 4096;
}
}
}
int mmap(const unsigned int virtual, const unsigned int physical,const int flags)
{
if((physical % 4096) != 0)
return -1; //주소가 4096 바이트로 정렬되지 않음
vaddress *vaddr;
vaddr = (vaddress *) virtual;
unsigned int **page = (unsigned int**)PGD_ADDRESS + 1024;
pte_t *pte = (pte_t *)&page[vaddr->dir_index][vaddr->table_index];
if((pte->flags << 11) < 0) //P 비트를 부호 비트로 바꾼 후 1인경우
return 0; //페이지가 이미 사용중 (p 비트가 1)
pte->addr = pte->addr | (physical / 4096);
pte->flags = pte->flags | flags;
return 1; //성공
}
int munmap(const unsigned int virtual)
{
if((virtual % 4096) != 0)
return -1; //주소가 4096 바이트로 정렬되지 않음
vaddress *vaddr = (vaddress *) virtual;
unsigned int **page = (unsigned int **)PGD_ADDRESS + 1024;
pte_t *pte = (pte_t *)&page[vaddr->dir_index][vaddr->table_index];
pte->addr = pte->addr ^ pte->addr; //a xor a 는 a=0과 같다.
pte->flags = pte->flags ^ pte->flags;
return 1;
}
void alloc_pages()
{}
void free_pages()
{}
void get_free_pages()
{}
void enable_paging()
{
unsigned int cr0;
__asm__ __volatile__("mov %0, %%cr3" : : "b"(PGD_ADDRESS));
__asm__ __volatile__("mov %%cr0, %0": "=r"(cr0));
cr0 |= 0x80000000;
__asm__ __volatile__("mov %0, %%cr0":: "r"(cr0));
return;
}
---- end of page.c ----
and I uploaded the entire source code.
help me!