my OS reboots when it enables paging

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Hygon
Posts: 4
Joined: Mon Jan 11, 2016 9:26 am

my OS reboots when it enables paging

Post by Hygon »

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..)

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!
Attachments
Gonio.zip
(40.51 KiB) Downloaded 50 times
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: my OS reboots when it enables paging

Post by iansjack »

Run your code under a debugger. Set a breakpoint just before you enable paging and check your page tables to see that they contain what you think they should. You should also check your GDT and IDT to see that they look reasonable. Also set breakpoints at the start of your handlers for page fault exceptions and GPF exceptions. That way you can tell the nature of the initial fault and, if it is a page fault, the address causing that fault.

With that information at you disposal it should be easy to review your code to see where the error lies.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: my OS reboots when it enables paging

Post by gerryg400 »

Code: Select all

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;
}
You didn't initialise the variable i
If a trainstation is where trains stop, what is a workstation ?
digo_rp
Member
Member
Posts: 233
Joined: Sun Jun 05, 2005 11:00 pm

Re: my OS reboots when it enables paging

Post by digo_rp »

try to learn with identy map 1:1 its the simplest way to learn paging...

first you should init your page_dir with all "0" zeroes.

Something like this!

for ( i = 0; i < 1024; i++ )
{
PageDir.Present = 0;
PageDir.ReadWrite = 1;
PageDir.Supervisor = 0;
PageDir.WriteThrough = 0;
PageDir.PageSize = 0;
PageDir.PageTableBaseAddress = 0;
}

then init pagetable with size of your kernel...

Address4KB = 0;

for ( i = 0; i < 1024; i++ )
{
PageTable.Present = 1;
PageTable.ReadWrite = 1;
PageTable.WriteThrough = 1;
PageTable.CacheDisabled = 0;
PageTable[i].Supervisor = Supervisor;
PageTable[i].GlobalPage = GlobalPage;
PageTable[i].PageBaseAddress = ((Address4KB & PBA_MASK) >> PAGE_SHIFT);

Address4KB += 4096;
}

that code above will map the first 4MB of memory

then finally set page_dir entry[0].

AddrPTE = PageTable;
PageDir[0].Present = 1;
PageDir[0].ReadWrite = 1;
PageDir[0].Supervisor = 1;
PageDir[0].WriteThrough = 1;
PageDir[0].PageSize = 0;
PageDir[0].GlobalPage = GlobalPage;
PageDir[0].PageTableBaseAddress = (((unsigned)AddrPTE & PTBA_MASK) >> PAGE_SHIFT);


This is the simplest way to use paging!

sorry for my poor english... :D

I hope this helps
Hygon
Posts: 4
Joined: Mon Jan 11, 2016 9:26 am

Re: my OS reboots when it enables paging

Post by Hygon »

Thanks! I'l try to do it.
and actually I didn't initialized zero spaces to zero!
Hygon
Posts: 4
Joined: Mon Jan 11, 2016 9:26 am

Re: my OS reboots when it enables paging

Post by Hygon »

iansjack wrote:Run your code under a debugger. Set a breakpoint just before you enable paging and check your page tables to see that they contain what you think they should. You should also check your GDT and IDT to see that they look reasonable. Also set breakpoints at the start of your handlers for page fault exceptions and GPF exceptions. That way you can tell the nature of the initial fault and, if it is a page fault, the address causing that fault.

With that information at you disposal it should be easy to review your code to see where the error lies.
Thanks!
Hygon
Posts: 4
Joined: Mon Jan 11, 2016 9:26 am

Re: my OS reboots when it enables paging

Post by Hygon »

gerryg400 wrote:

Code: Select all

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;
}
You didn't initialise the variable i
Thank you! I didn't catch it
Post Reply