Page 1 of 2

Problems understanding paging

Posted: Sat Jun 26, 2004 5:20 am
by Freanan
As i know, most OSes, for example Linux, use paging to manage the memory.
But under Linux an user application thinks, it had a .text, .data and .bss segment! I don't understand, how paging and segmentation can work together...
Another similiar problem: To implement multitasking, a tss
- a task state SEGMENT is needed to store data about a task. But if there is no segmentation anymore, how can i have a tss?
Please bring some light into the matter!

Re:Problems understanding paging

Posted: Sat Jun 26, 2004 6:31 am
by Brendan
Hi,
Freanan wrote: As i know, most OSes, for example Linux, use paging to manage the memory.
But under Linux an user application thinks, it had a .text, .data and .bss segment! I don't understand, how paging and segmentation can work together...
This is because the term "segment" means 2 completely different things. The .text, .data and .bss segments are just areas in virtual memory and would be better described as "areas" to avoid confusion.
Freanan wrote: Another similiar problem: To implement multitasking, a tss
- a task state SEGMENT is needed to store data about a task. But if there is no segmentation anymore, how can i have a tss?
Please bring some light into the matter!
In 32 bit protected mode you can't disable the segment registers. The best you can do is to set them with base = 0 and limit = 4Gb and pretend that they aren't there (although it's possibly better to make more use of them in some cases, especially CS limit).

I think your confusion comes from thinking "there is no segmentation anymore". There is, even the new 64 bit CPUs (when they are running in 64 bit mode) still make some use of segments (although much less).

Of course it's also possible (in 32 bit protected mode) to make full use of segmentation AND paging. See the diagram in "3.2.3. Multi-Segment Model" of "IA-32 Intel Architecture Software Developer?s Manual, Volume 3: System Programming Guide". Most OS's don't use segmentation this much (too complex to manage efficiently), but an OS could if it wanted to.


Cheers,

Brendan

Re:Problems understanding paging

Posted: Sat Jun 26, 2004 9:19 am
by Freanan
Thanks for your help!

I understand the thing about linux...

So i can use a task state segment and paging in the same time, by just defining the tss and ignoring the pages so far..?
I'll read the part of the documentation you recommended!

Re:Problems understanding paging

Posted: Sun Jun 27, 2004 3:17 am
by Freanan
OK, i think i understand some things better now:
I can use paging and segmentation in the same time.
The Intel manual told me, that without paging the linear adress that is made from the (segmentation's) logical adress is directly passed to the adress bus. With paging enabled this calculated linear adress is used to calculate the real physical adress.

But this brings another question to my mind:
The linear adress that is built by segmentation is

Code: Select all

[segment_start+offset]
While the linear adress that is used with paging is

Code: Select all

[pagedir_index; pagetable_index; offset_in_page]
The linear adress built with segmentation is just a number that points to the physical adress, while with paging enabled the processor expects an adress built of three parts...
How can the processor interpret the linear adress that is calculated when segmentation is used (single number) in the way that is expected when paging is used (two indexes, one offset)?

Re:Problems understanding paging

Posted: Sun Jun 27, 2004 4:28 am
by Brendan
Hi,
Freanan wrote: How can the processor interpret the linear adress that is calculated when segmentation is used (single number) in the way that is expected when paging is used (two indexes, one offset)?
Let's say you've got the address "0xBA98:0x76543210", segmentation and paging. Now the segment "0xBA98" is used as an index into the GDT, where the CPU checks the limit and grabs the base address. The base address is added to the offset, for e.g. if the base = 0x10000000 then the CPU adds it to 0x76543210 to get the logical address 0x86543210.

Then the CPU splits this logical address into components (which depend on the paging mechanism being used). Let's assume the original mechanism is in use (4 Kb pages, PAE=0, PSE=0). The lowest 12 bits become the offset into the page, the highest 10 bits are an index into the page directory (to determine the physical address of the page table), and the middle 10 bits are an index into the page table (to determine the physical address of the page).

It's easier to split this into bits:

Code: Select all

 1000011001 0101000011 001000010000  = 0x86543210
 dddddddddd pppppppppp oooooooooooo

Where:
 d = 1000011001 = 0x219 = page directory index
 p = 0101000011 = 0x143 = page table index
 o = 001000010000 = 0x210 = offset
So the CPU looks at entry number 0x219 in the page directory to find the physical address of the page table. Then it looks at entry number 0x143 of this page table to find the physical address of the actual page. Once it's found the physical address of the page it just adds the offset part.

More specifically:
logicalAddress = GDTorLDT[segment] + offset
pageDirAddress = CR3
pageTableAddress = pageDirAddress[logicalAddress >> 22]
pageAddress = pageTableAddress[(logicalAddress >> 12) & 0x3FF]
physicalAddress = pageAddress + (logicalAddress & 0xFFF)

When you add different paging mechanisms, different CPU modes, all the protection checks and several different types of caching you can understand just how complex the CPU is :)

Cheers,

Brendan

Re:Problems understanding paging

Posted: Sun Jun 27, 2004 4:52 am
by Freanan
I understand (though it seems really strange to me, that this works ;) )
Thanks!

Re:Problems understanding paging

Posted: Sun Jun 27, 2004 12:08 pm
by Freanan
Now, thinking that i understand everything more or less i decided to implement some basic paging....
I basically followed the advice/instructions/code of the "Implementing Basic Paging" Tutorial by K.J...
But the system reboots just after i enabled the paging bit.
Off course i installed the page directory and one page table first...
The remaining entries of the page directory are all set to "page not present", so that they are ignored.. (i also tried to map all the memory and not just the first 1024 pages for debugging purposes, but it also rebooted)

Has someone an idea how this happens and what i can do?
I would have read the complete sourcecode of the tutorial that i used to compare it with my own code, but the download did not work

Below there are the relevant parts of my code..
It is assembled with nasm, compiled with gcc and linked with ld, the loader loads the kernel to 0x1000 and sets up pmode.
i also have segmentation, but i use it like "flat mode" - code and data segments overlapping each other having a size of 4gb..
I also installed basic interrupt and exception handling, which works, so in fact i should have at least got a page fault or something....

Relevant parts of my assembler startup file:

Code: Select all

EXTERN prepare_paging
EXTERN page_dir

; ...

call prepare_paging    ;prepare page dir and page table
mov eax,[page_dir]     ;move the adress of the pagedir to cr3
mov cr3,eax
mov eax,cr0                ;set paging bit in cr0
or eax,0x80000000
mov cr0,eax                ;this is the point were the machine crashes

paging.h (header with included code)

Code: Select all

unsigned long *page_dir;
unsigned long *page table;

unsigned long adress;
unsigned int j;

void prepare_paging(void)
{
   adress=0;
   page_dir=(unsigned long*)0x9C000;
   page_table=(unsigned long*)0x9D000;

    //set up the page table with 1024 entries
   for(j=0; j<1024; j++)
   {
       page_table[j]=adress | 3;  //attributes= 3= 011
       adress= adress+4096;     //next start adress is 4 kb above
   };

   //set the first entry of the pagedir to the pagetable
   page_dir[0]= page_table;
   page_dir[0]= page_dir[0] | 3;

   //make the rest inaccessible
   for(j=1; j<1024; j++)
       page_dir[j]= 0 | 2;
};


Re:Problems understanding paging

Posted: Sun Jun 27, 2004 10:46 pm
by Brendan
Hi,
Freanan wrote:

Code: Select all

   for(j=0; j<1024; j++)
   {
       page_table[i]=adress | 3;  //attributes= 3= 011
       adress= adress+4096;     //next start adress is 4 kb above
   };
What is "i", and did you mean "page_table[j] = address | 3"?

Cheers,

Brendan

Re:Problems understanding paging

Posted: Mon Jun 28, 2004 7:13 am
by Freanan
Sorry, i means j - this must have crept into the code while i was posting it here... (otherwise it would have been a compiler-syntax-error)

Yes, that is what i meant.
Any idea what the problem might be..?
Something about my page directory and/or my pagetable must be wrong, but i can't see what..

Re:Problems understanding paging

Posted: Mon Jun 28, 2004 7:46 am
by Brendan
Hi,
Freanan wrote: Sorry, i means j - this must have crept into the code while i was posting it here... (otherwise it would have been a compiler-syntax-error)
Other than the "i" typo I couldn't find anything. Could you step through it with Bochs? If so, stop just before paging is enabled and make sure everything points where it should (starting from CR3 and working down to physical pages) and that the protection flags are correct..

Cheers,

Brendan

Re:Problems understanding paging

Posted: Tue Jun 29, 2004 2:44 pm
by Freanan
OK, i examined the cpu-registers as well as the page directory and page table - this is the relevant output of dump_cpu and xp commandos of bochs:

Code: Select all

eax=cr0=0x60000011       //should be right
cr3=0x9C000                     //  " "
pagedir[0]=0x0009D003    //  " "
But i think this is wrong: The first page in the page table should point to memory location 0 and therefore contain 0|3 =3

Code: Select all

pagetable[0]=0x003ff003
Another strange thing is, that bochs added the note <bogus +0>:
to the output of the xp commands... What does that mean?

Re:Problems understanding paging

Posted: Wed Jun 30, 2004 12:06 am
by Brendan
Hi,
Freanan wrote:

Code: Select all

pagetable[0]=0x003ff003
0x003ff003 = 4096 * 1023 | 3

If pageTable[1 to 1023] don't make any sense at all I'd suggest that your code isn't using "j", for e.g.:

Code: Select all

for(j=0; j<1024; j++)
  {
      page_table[0]=adress | 3;  //attributes= 3= 011
      adress= adress+4096;    //next start adress is 4 kb above
  };
The code above would produce the same results even though it's obviously wrong..
Freanan wrote: Another strange thing is, that bochs added the note <bogus +0>:
to the output of the xp commands... What does that mean?
I get the "bogus" thing too - I'm not sure what it means (if anything). I've always ignored it :) The value after the "bogus" is the number of bytes displayed before the start of the line, so if you did "xp /32 0" the first line would be "bogus +0", the second would be "bogus +16", etc.


Cheers,

Brendan

Re:Problems understanding paging

Posted: Wed Jun 30, 2004 6:10 am
by Freanan
Oh, i just found the error!
The page_table was not a typo that crept into the code while posting it here... it was really inside my code. And it did not cause an compile-error because the variable i indeed exists inside my code.
Sorry for causing so much trouble because of that little sillyness on my side ;)

After changing that, the sytsem does not reboot anymore, but it also does not work as it should: I get some exception (i don't know yet which one it is, because i have one handler for all of them)..
I think i will try to find out which instruction causes the exception, and which exception it is and come back afterwards..

Re:Problems understanding paging

Posted: Wed Jun 30, 2004 1:57 pm
by Freanan
OK, i tried to debug the new error/exception...
Now there are three strange things:

1. I was not able to determine which exception exactly occured, because after i added different handlers for all the exceptions instead of just one for al exceptions,
another exception, a general protection fault, occured earlier in the code. Why can that be..?

2. Removed the different handlers again...
Now i tried to step through the code, using
endless for(;;); - loops as some kind of primitive breakpoint.
I also have some status-textoutputs in the main function.
Now i noticed that, from a certain point on, no new messages are printed, but the old messages on the screen get deleted (and this did not happen in the beginning, my kprint-function always worked well)! Might i write data to the videomemory accidentally? Would be strange in fact, because the instructions in my main function only do remap the pic and unmask the irq for keyboard and printer...

3. When i remove all the print-instructions from my main kernel function, except one little message at the end, everything works fine again (but of course i want my textoutput, and i need to know why it does only work without it)!

Re:Problems understanding paging

Posted: Sun Jul 04, 2004 1:01 pm
by Neo
just checking but have you linked ur kernel to run at the right address?