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.
I've wrote some code to implement the virtual memory, but it comes lots of faults.
In the setup_page() function, I have initialize all the memory like that:
void setup_page(void)
{
/* PG_DIR is defined as 0x800000, and PG_TABLE is defined as (PG_DIR + PG_SIZE)*/
unsigned long address = 0;
unsigned long table = PG_TABLE;
int i;
for (i=0; i<PG_PAGES; i++) {
pg_table[i] = address | 7;
address += PG_SIZE; /*PG_SIZE is 4K*/
}
for (i=0; i<8; i++) {
pg_dir[i] = table | 7;
table += PG_SIZE;
}
for (; i<1024;i++)
pg_dir[i] = 6;
__asm__("movl $0x800000,%%eax\n"
"movl %%eax, %%cr3\n"
"movl %%cr0, %%eax\n"
"orl $0x80000000, %%eax\n"
"movl %%eax, %%cr0\n"
::"a"(PG_DIR));
}
As i set all the Present bit of all the memory i have(32 M), i except nothing wrong would happened. But i almost get the same message:
The wrong address is 0x80000400. (I just handle the wrong address and halt).
And i don't understand what does the address 0x80000400 mean. With i enabled the paging system, it would handle some address more understandable like 0x00410000 but not 0x80000400 (And i don't think it's a **LINE** address...)
Thanks a lot.
Obviously, something is accessing a location it should not.
Your page fault handler gets a lot more information than just the faulting address, try printing the error code and return address as well. That should tell you what is causing the error, and may give you an idea as to the "why".
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Just a guess, but it looks like you have taken something like the contents of CR0 (in other words a flag-type register) and are trying to access it as a memory location. The value 0x80000400 would just have flags at bits 31 and 10 set.
iammisc wrote:Why don't you look at the eip in your fault handler and determine exactly where your kernel is faulting?
I can find the eip in the bochs log file, but how can i find the wrong address in which function or in the function itself though i knew the eip, say 0x000038da.
Last edited by negcit.K on Fri May 30, 2008 2:13 am, edited 1 time in total.
return (*v & (1<<(7-(i%8)))) != 0; /*In function testb()*/
and when i shrink the range, i found some sentence like *v,that is to say read value of somewhere, It would invoke the page fault handler and print out the wrong address : 0x80000400.
but when i test the sentence like in mem_debug() (a function in mm.c) , it would not happen.
I debug it a long time but nothing can work, so i really need your help.
Thanks!
That statement does not deserve to work. Have you got all compiler warnings turned on (not just -Wall - see the more comprehensive list in Solar's Makefile tutorial ) including -Werror?
Could you just clarify what that's supposed to do? I think the only thing that could cause a page fault there is the dereferencing of v. What value does v contain? I bet it is 0x80000400. When you dereference it, you try to read from that address.
'+' has higher precedence than '<<'. This means that you add 2 to 'start', getting the value 0x400002, and then shift the whole answer by 9 bits, giving a result of guess what value?*
void do_no_page(unsigned long address, long fs, long es, long ds, unsigned long edx, unsigned long ecx, unsigned long error_code, unsigned long eip, unsigned long cs, unsigned long eflags, unsigned long esp, unsigned long ss)
{
printk("\nTHE PAGE FAULT INFORMATION\n\n");
printk("THE FAULT ADDRESS:\t%p\n",address);
printk("EIP:\t%p:%p\n",cs,eip);
printk("ESP:\t%p:%p\n",ss,esp);
printk("EFLAGS:\t%p\n",eflags);
printk("ERROR_CODE:%p\n",error_code);
printk("ds:\t%p\nes:\t%p\nfs:\t%p\n",ds,es,fs);
while(1)
;
}
Have you changed your code as per my previous post and you are still getting the same PFE, or did that work and you just want help with this different question now?
Thank you AJ.
I changed the code, then rewrite the page fault handler program, and the out message just like the previous saying.
I think the wrong part is my page fault handler, so i paste it here.And AJ, Can you give me some advise on how to fix it up.
I'm afraid I'm not too happy with AT&T syntax and do my exception handling quite differently, but for a start you should be saving all registers with a pushad, which I can't see. Maybe someone else can help you more with this.
Can I also suggest that once you have pushed all the registers, you save the value of esp on to the stack (save it in eax first). This means that you will just pass one parameter to your C code, which is a pointer to all the other registers you need. Have a look at James Molloy's Tutorials - specifically the one on IRQ's. This will give you a better idea about interrupt wrapping.
If you continue with interrupt handlers like the one you have there, I think the kernel is going to get messy very quickly.