Page 1 of 1

Error in Setting Up Paging?

Posted: Thu Aug 15, 2013 9:05 am
by narke
This tutorial is very cool but there is a line:

Code: Select all

//our first page table comes right after the page directory
unsigned int *first_page_table = page_directory + 0x1000;
The thing is that page_directory and first_page_table are declared as pointers to integers, for example on 32-bit Intel an int is 4 bytes long, so if you advance a pointer to an integer by 1 in fact you will advance by 4 bytes in the memory region.
So, as 0x1000 = 4096, in fact it will advance in memory by 0x1000 * 4 = 4096 * 4 = 16384.

But we need to advance only by 4096 bytes (0x400 in hex) becauses the next page table is in 4096 bytes.

So the correct line should be:

Code: Select all

//our first page table comes right after the page directory (4096 bytes offset), 
unsigned int *first_page_table = page_directory + 1024;
Isn't it?

Re: Error in Setting Up Paging?

Posted: Thu Aug 15, 2013 1:29 pm
by AndrewBuckley
I think in C there might be a difference between nth elements in an array and adding to an address. could be wrong.
u32int array
array[1] != ptr_to_array +1
??

Re: Error in Setting Up Paging?

Posted: Thu Aug 15, 2013 1:36 pm
by iansjack
Merlin wrote: could be wrong.
Well, at least you got that bit right.

Re: Error in Setting Up Paging?

Posted: Thu Aug 15, 2013 2:36 pm
by sortie
In the C programming language, the expression ptr[index] is actually the same as typing *(ptr + index). Indeed, the [] operator is just syntactic sugar. Curiously, *(ptr + index) is the same as *(index + ptr) which through the first rule is the same as index[ptr].

Re: Error in Setting Up Paging?

Posted: Fri Aug 16, 2013 10:04 pm
by bluemoon
sortie wrote:Curiously, *(ptr + index) is the same as *(index + ptr) which through the first rule is the same as index[ptr].
No, you need to consider data type in question too (which is crucial to produce final memory address), *(ptr + index) uses ptr as current data type, while *(index + ptr) uses index.

Re: Error in Setting Up Paging?

Posted: Sat Aug 17, 2013 4:30 am
by Griwes
No, it doesn't, it uses pointer's type, regardless of its position in the expression.

And for the original problem, there are about three possible solutions: change the 0x1000 to 1024 AND change the pointer's type to uint32_t (so it's always 4096 bytes), add a sane datatypes of size of 4096 that represent paging structures (and use + 1 and cast to proper type) or use an integer, not a pointer, to calculate those addresses and cast that integer to pointers to either uint32_t or proper types representing paging structures.

Re: Error in Setting Up Paging?

Posted: Sat Aug 17, 2013 4:33 am
by dozniak
bluemoon wrote:
sortie wrote:Curiously, *(ptr + index) is the same as *(index + ptr) which through the first rule is the same as index[ptr].
No, you need to consider data type in question too (which is crucial to produce final memory address), *(ptr + index) uses ptr as current data type, while *(index + ptr) uses index.
No, since index is size_t or ssize_t compatible type, the dereference would not work if it was used as the base type in such expression.

It's easy to illustrate with the simple code snippet:

Code: Select all

#include <stdio.h>
#include <stdint.h>

int main()
{
    uint64_t arr[]={1,2,3};
    uint32_t agg[]={5,6,7};

    printf("%llu\n", *(arr+1)); // 2
    printf("%llu\n", *(1+arr)); // 2, not 0x0200 0000 0000 0000
    printf("%u\n", *(agg+2)); // 7
    printf("%u\n", *(2+agg)); // 7, not 0x0006 0000
}