Page 3 of 5
Re:Enabling Paging
Posted: Wed Jul 27, 2005 3:01 pm
by Freanan
Yes i call this from C as a function..
I changed it as you said, but there must be more errors, for my kernel still hangs.
I also tried to put the call to my C-highlevel-paging-setup function below the code that sets up interrupts and enables them, hoping to gain information from the message of the exception handler, but bochs does still only hang.
I will probably try to get more informartion using the bochs debugger tomorrow (it is night here now and i am tired
).
Re:Enabling Paging
Posted: Wed Jul 27, 2005 5:40 pm
by AR
JoeKayzA's code is backwards, Intel syntax is "instruction dest, src", he's actually writing EAX to the stack, it should be "mov eax, [esp+4]". I can't see anything else wrong with that particular piece of code.
Re:Enabling Paging
Posted: Wed Jul 27, 2005 11:13 pm
by JoeKayzA
AR wrote:
JoeKayzA's code is backwards, Intel syntax is "instruction dest, src", he's actually writing EAX to the stack, it should be "mov eax, [esp+4]". I can't see anything else wrong with that particular piece of code.
Oh, god, I saw that coming, I DID confuse with Intel syntax
anyway, thx
Joe
Re:Enabling Paging
Posted: Wed Jul 27, 2005 11:21 pm
by Freanan
I had noticed the backwardness
So the problem must still be something else.
I have messages in my code that tell me how far execution got, it stops after it wants to init paging.
Strangely, when i add code for putting single chars to the screen in the assembler-routine, i do not even get as far as that and execution stops even before i display the message, ie before that code is executed
.
I'll post all my paging code when i am at home again - can't do any harm
EDIT: I have a question about paging that has nothing to do with my actual problem:
Why do we use methods like a page stack or a bitmap to determine which pages are in use an which can be given away to processes, when there are "available"-bits in the entries of the page directory and page table? One could just use those to mark whole page tables or single pages as unused or used..?
Re:Enabling Paging
Posted: Thu Jul 28, 2005 12:46 am
by JoeKayzA
Hi!
Freanan wrote:
EDIT: I have a question about paging that has nothing to do with my actual problem:
Why do we use methods like a page stack or a bitmap to determine which pages are in use an which can be given away to processes, when there are "available"-bits in the entries of the page directory and page table? One could just use those to mark whole page tables or single pages as unused or used..?
Don't confuse: the page stacks (or bitmaps) that keep track of which page is used normally belong to the PHYSICAL memory manager. You use it to find a free physical page, before you map it into some process' address space. The available bits in the page tables could only take care of whether a page is used or not *inside* a process.
cheers JOe
Re:Enabling Paging
Posted: Thu Jul 28, 2005 2:16 am
by Kim
If you use a local var for your page directory (array of 1024 dword items) it could be that the physical address of that array isn't paged aligned. This is sure to make crashes/errors.
Re:Enabling Paging
Posted: Thu Jul 28, 2005 2:26 am
by Freanan
So the stack/bitmap are supposed to show which pieces of physical memory are free to be associated with pages (entries in a page table), while the bits could only be used to indicate the availability of an already mapped page?
Re:Enabling Paging
Posted: Thu Jul 28, 2005 3:54 am
by AR
The virtual address space is mapped via the page directories and tables, the tables are just lists of pointers to physical pages, the page management mechanisms I was talking about are for allocating the physical pages for use in the page tables and keeping track of which ones currently aren't in use.
An approach for managing pages that belong to a process could use a tree linked to the process struct which simply tracks which pages aren't currently mapped so that the page directory and tables can be rebuilt when the page is needed and hold identifiers for loading the page back from the swap.
Re:Enabling Paging
Posted: Thu Jul 28, 2005 4:17 am
by JoeKayzA
AR wrote:
An approach for managing pages that belong to a process could use a tree linked to the process struct which simply tracks which pages aren't currently mapped so that the page directory and tables can be rebuilt when the page is needed and hold identifiers for loading the page back from the swap.
True, I was also thinking that you should hold a data structure with linear->physical mappings on your own, independent from the mmu's page dirs and tables. This helps you with platform independence, and you can more easily extend the information on specific pages than just using those few 'available' bits, when you have, for example, multi-level-mapping techniques (have a look at my memory objects in 'OS-design' thread).
For the very beginning however, I would recommend to stick with x86' page mapping structures, and when a page is unavailable for some reason (swapped out, for ex.), simply unset the 'present' bit, and you can reuse all 31 remaining bits in the page table entry for a pointer to more information on the actual state of the page (where it resides in swap space etc...).
cheers Joe
Re:Enabling Paging
Posted: Thu Jul 28, 2005 5:54 am
by Freanan
Okay, i used the debuger now.
It does not tell me much, except that the cpu crahes either at
mov cr0,eax
or at the return afterwards.
I also did a dump_cpu... Here are the interresting parts of the log of the debug session:
Code: Select all
(0).[18393492] [0x0010133e] 0008:0010133e (unk. ctxt): mov dword ptr ss:[esp+], 0x107860 ; c7042460781000
(0).[18393493] [0x00101345] 0008:00101345 (unk. ctxt): call 0x100033 ; e8e9ecffff
(0).[18393494] [0x00100033] 0008:00100033 (unk. ctxt): mov eax, dword ptr ss:[esp+0x4] ; 8b442404
(0).[18393495] [0x00100037] 0008:00100037 (unk. ctxt): mov cr3, eax ; 0f22d8
(0).[18393496] [0x0010003a] 0008:0010003a (unk. ctxt): mov eax, cr0 ; 0f20c0
(0).[18393497] [0x0010003d] 0008:0010003d (unk. ctxt): or eax, 0x80000000 ; 0d00000080
(0) Breakpoint 2, 0x100042 in ?? ()
Next at t=18393498
(0) [0x00100042] 0008:00100042 (unk. ctxt): mov cr0, eax ; 0f22c0
dump_cpu
eax:0xe0000011
ebx:0x106860
ecx:0x400000
edx:0x400
ebp:0x104ff8
esi:0x54617
edi:0x54618
esp:0x104fdc
eflags:0x212
eip:0x100042
cs:s=0x8, dl=0xffff, dh=0xcf9a00, valid=1
ss:s=0x10, dl=0xffff, dh=0xcf9300, valid=7
ds:s=0x10, dl=0xffff, dh=0xcf9200, valid=7
es:s=0x10, dl=0xffff, dh=0xcf9300, valid=1
fs:s=0x10, dl=0xffff, dh=0xcf9300, valid=1
gs:s=0x10, dl=0xffff, dh=0xcf9300, valid=1
ldtr:s=0x0, dl=0x0, dh=0x0, valid=0
tr:s=0x0, dl=0x0, dh=0x0, valid=0
gdtr:base=0x10600e, limit=0x17
idtr:base=0x106060, limit=0x7ff
dr0:0x0
dr1:0x0
dr2:0x0
dr3:0x0
dr6:0xffff0ff0
dr7:0x400
tr3:0x0
tr4:0x0
tr5:0x0
tr6:0x0
tr7:0x0
cr0:0x60000011
cr1:0x0
cr2:0x0
cr3:0x107860
cr4:0x0
inhibit_mask:0
done
c
(0).[18393498] [0x00100042] 0008:00100042 (unk. ctxt): mov cr0, eax ; 0f22c0
Maybe i have a wrong return-pointer as well?
It seems plausible, as the cpu crashes at the return-line...
Here is, as i said, my C-code. Maybe i made a mistake when i changed the code from the tutorial into mine....
Code: Select all
#include "../include/paging.h"
unsigned long page_dir[1024]; //Space reserved for the page directory
unsigned long page_table[1024]; //One page table
//Set up an entry in the page directory to point to a page table
void set_pagedirentry(int pos, unsigned long* table_adress, unsigned short flags)
{
page_dir[pos]=table_adress;
page_dir[pos]=page_dir[pos] | flags;
};
//Set up an entry in the page table to point to a physical starting adress
void set_pagetableentry(int pos, unsigned long addr, unsigned long* table_adress, unsigned short flags)
{
if(pos>=1024)
return;
else
table_adress[pos]=addr | flags;
};
//Set up Paging for the first 4MB of physical memory
void setup_paging()
{
int i;
unsigned long adress;
adress=0;
for(i=0; i<1024; i++)
{
set_pagetableentry(i, adress, page_table, 3);
adress+=4096;
};
set_pagedirentry(0, page_table, 3);
for(i=1; i<1024; i++)
set_pagedirentry(i, (unsigned long*) 0, 2);
start_paging(page_dir);
};
I hope it helps helping me
Re:Enabling Paging
Posted: Thu Jul 28, 2005 5:57 am
by Kemp
Have you checked that once you enable paging the address it's trying to return to is a real address (ie, you haven't remapped that part of memory and forgot to adjust the return pointer)?
Re:Enabling Paging
Posted: Thu Jul 28, 2005 6:04 am
by AR
unsigned long page_dir[1024]; //Space reserved for the page directory
unsigned long page_table[1024]; //One page table
...
set_pagedirentry(0, page_table, 3);
Bad, very bad. Page Tables MUST be page aligned, that does not do any aligning at all. The low 12bits are flags in the page directory, but since your page table isn't aligned you are trying to use those low parts as part of the address which just makes a mess.
Re:Enabling Paging
Posted: Thu Jul 28, 2005 6:17 am
by Kim
Kim wrote:
If you use a local var for your page directory (array of 1024 dword items) it could be that the physical address of that array isn't paged aligned. This is sure to make crashes/errors.
I allready posted that
cr3 lowest 12bits must be zero aka page aligned, note this not true when PAE is on... your best source of information are the intel docs ... some tutorials are missing stuff you will find in those docs.
Re:Enabling Paging
Posted: Thu Jul 28, 2005 6:18 am
by Freanan
AR wrote:
unsigned long page_dir[1024]; //Space reserved for the page directory
unsigned long page_table[1024]; //One page table
...
set_pagedirentry(0, page_table, 3);
Bad, very bad. Page Tables MUST be page aligned, that does not do any aligning at all. The low 12bits are flags in the page directory, but since your page table isn't aligned you are trying to use those low parts as part of the address which just makes a mess.
Aha!
Is there any way to align it in C?
Or would it help to do it like that in my asm file:
Code: Select all
global page_dir
global page_table
ALIGN 4096
page_dir:
resdw 1024
page_table:
resdw 1024
@Kemp: As far as i know all the memory is mapped to itsself, yes.
Re:Enabling Paging
Posted: Thu Jul 28, 2005 6:22 am
by Solar
Freanan wrote:
Is there any way to align it in C?
Not in C. You might be lucky in finding a compiler extension doing alignment for you, but otherwise this is typical ASM stuff. (Memory management as a whole, actually, since we're speaking of a highly performance-critical part of your OS here. Memory management, interrupt handling, lower half of device drivers, possibly scheduling - this is where ASM rules.