Page 1 of 1

problem with bit manipulation

Posted: Sat Jun 20, 2009 1:47 pm
by yemista
Im trying to manipulate the bits in the page directory, but they are not being stored in memory as they should be.

Code: Select all

typedef struct page {
   u32 present    : 1;   // Page present in memory
   u32 rw         : 1;   // Read-only if clear, readwrite if set
   u32 user       : 1;   // Supervisor level only if clear
   u32 accessed   : 1;   // Has the page been accessed since last refresh?
   u32 dirty      : 1;   // Has the page been written to since last refresh?
   u32 unused     : 7;   // Amalgamation of unused and reserved bits
   u32 frame      : 20;  // Frame address (shifted right 12 bits)
} page_t;

 for(i = PG_ALIGN(start), j = 0xff; i < PG_ALIGN(end+0x1000); i += 0x1000, ++j) {
    idx = first_frame();
    user_pde->tables[PDE_OFFSET(i)]->pages[PTE_OFFSET(i)].frame = j;
    user_pde->tables[PDE_OFFSET(i)]->pages[PTE_OFFSET(i)].present = 1;
    user_pde->tables[PDE_OFFSET(i)]->pages[PTE_OFFSET(i)].user = 1;
    set_frame(idx*0x1000);
  }
j is just there for debugging purposes, but i would get the same problem while using idx.
Most of this code was taken from JamesM, and it works in his kernel, so i dont know what im missing here.

Here is the contents of the page table from bochs:

Code: Select all

<bochs:2> x /10 0xd0004000
[bochs]:
0xd0004000 <bogus+       0>:	0x05000000	 0x05000ff0	0x05001000	 0x05001010
0xd0004010 <bogus+      16>:	0x05001020	 0x05001030 0x05001040 0x05001050
0xd0004020 <bogus+      32>:	0x05001060	0x05001070
So you see what is happening is present and user are being treated as the leftmost byte, and frame is being treated as, im guessing, this part 0x05000ff0. Why aren't the bits being stored in memory as defined by the structure?

Re: problem with bit manipulation

Posted: Sat Jun 20, 2009 2:07 pm
by Tomaka17
Did you try adding __attribute__((packed)) to the structure definition?

This was the cause of many bugs with my project

Re: problem with bit manipulation

Posted: Sat Jun 20, 2009 2:11 pm
by yemista
I just tried it and there was no difference. Ive also tried defining frame as the first element of the structure rather than the last, but it still comes out the same. My best guess it has something to do with x86 being little endian, so its storing the bytes backwards or something, but thats just a thought and i really dont know

Re: problem with bit manipulation

Posted: Sat Jun 20, 2009 2:32 pm
by thooot
Is your user_pde structure correct? I would either use the debugger to step through the code or add some print statements around it so you can see what its actually doing. Your bit manipulation looks fine. My guess would be you're not touching the memory you think you are.

*edit: You should zero out the page table entry before setting the present, user, frame bits. Otherwise the other bits could be garbage.

Re: problem with bit manipulation

Posted: Sat Jun 20, 2009 11:31 pm
by kop99
yemista, Here is your code...

Code: Select all

for(i = PG_ALIGN(start), j = 0xff; i < PG_ALIGN(end+0x1000); i += 0x1000, ++j)
Maybe you should try following code...

Code: Select all

for(i = PG_ALIGN(start), j = 0x0; i < PG_ALIGN(end+0x1000); i += 0x1000, ++j)

Re: problem with bit manipulation

Posted: Sun Jun 21, 2009 9:47 am
by yemista
it makes no difference. That j is only there for debugging purposes so I could see what was being stored in memory.

Here is what the page table looks like:

Code: Select all

Code:
<bochs:2> x /10 0xd0004000
[bochs]:
0xd0004000 <bogus+       0>:   0x05000000    [color=red]0x05000ff0[/color]   0x05001000    0x05001010
0xd0004010 <bogus+      16>:   0x05001020    0x05001030 0x05001040 0x05001050
0xd0004020 <bogus+      32>:   0x05001060   0x05001070
And here is what it should look like, with j starting at 0xff
0x000ff005

Re: problem with bit manipulation

Posted: Tue Jun 23, 2009 3:23 pm
by yemista
SOLVED

ended up being real buggy code. I want to emphasize to others the importance of having your own printf. Debugging can be impossible with out it