Problem with Paging and Mapping Code

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.
Post Reply
Slasher

Problem with Paging and Mapping Code

Post by Slasher »

hi everyone,
I'm having trouble setting my CS to a zero based selector after i enable paging.
In Bochs, once I execute the enable_paging section of code below, I get
00031837437e[CPU ] WARNING: Any simulation after this point is completely bogus.
00031837437p[CPU ] >>PANIC<< exception(): 3rd (14) exception with no resolution
this is the start stub code,written in NASM,that I link before k_main() to setup
1. The PAGE_DIR at PHYSICAL ADDRESS 0xC000,PAGE_TABLE_1 at PHYSICAL
ADDRESS 0xD000 and PAGE_TABLE2 at PHYSICAL ADDRESS 0xE000
2. set PAGE_DIR[0x0000] to point to PAGE_TABLE_1
3. set PAGE_DIR[0x0300] to point to PAGE_TABLE_2
4. perform a 1:1 mapping of addresses from 0 to 1MB into PAGE_TABLE_1
5. map LINEAR ADDRESS 0xC0000000(page directory entry 0x0300) to PHYSICAL ADDRESS 0x200000
6.Create a new gdt with zero based selectors for data and code by copying it to LINEAR ADDRESS 0x10000(which is the same as PHYSICAL ADDRESS cause of 1:1 mapping)
7. Load segment regs with zero based data selector
8. enable paging
9. try to load CS with zero base code selector and jump to k_main at 0xC0000xxx
its step 9,thats crashing Bochs. Don't Know why :'(
I'm not sure if its the jump or if my memory mapping is incorrect. Could you guys please look at this code and tell me what i'm obviously missing(its always a small significant detail) the code is attached as a file. Thanks.
PS: the kernel works fine cause i've been using it without paging but wanted to add virtual memory by using paging.


[attachment deleted by admin]
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problem with Paging and Mapping Code

Post by Pype.Clicker »

what i can say by a quick look is that it doesn't look clear. I'd need to read the whole code and draw a sketch of your memory organization in order to get an idea of what's going on ...
Slasher

Re:Problem with Paging and Mapping Code

Post by Slasher »

Do you mean the rest of the start up code that calls this stub? I've attached it below. I've done all sorts of calculations and reprogramming for over 9+ hrs each day and night for about the last 5 - 6 days now with little change. But when i tried paging at first with a 1:1 mapping(instead of 0x200000 mapped to 0xC0000000) from my C kernel, it work fine so i don't know why it failed when i changed my mapping.
PS: I copied both protos.asm and kboot.asm together cause i couldn't attached 2 files.
Protos.bin is loaded by BIOS to 0000:7c00 and then protos.bin loads kboot.bin to 0000:5000. Kboot then loads the C kernel(which doesn't do any paging initialization) and jumps using a code selector that has base 0x40200000 to 0xC0000000 (this will end up as 0x200000 where the kernel is really loaded). The stub (attached in previous code) is linked to the start of the C kernel,so it gets called by kboot to setup the paging and new gdt before the stub calls k_main.



[attachment deleted by admin]
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problem with Paging and Mapping Code

Post by Pype.Clicker »

hmm ... so if i understand correctly your config, kboot sets up segments 0x18 and 0x20 to be 'temporary' kernel code and segments which allow you to run code linked to be executed at 0xC000_0000 before paging is activated.

What troubles me in stub.asm:_start is the way you address page tables. If your valid address range for the kernel is 0xC000_0000, is it correct to use TEMP_PAGE_DIR = 0xc000 ? Are you using physical memory at 0x4020C000 or do this code still work with DS=SYS_LINEAR_SEL ?

assuming that you actually planned this, your entries in the page directory should at least have their 'present' bit set ...
Slasher

Re:Problem with Paging and Mapping Code

Post by Slasher »

Yes,kboot sets the segment base for CS to 0x40200000.
what i did was,I have 2 tables which i used for mapping. The first table is mapped from 0 to 4mb and the 2nd is mapped from 0xC0000000 - 0xC0400000.
But the thing is,from kboot I set the segments DS,ES,FS and GS to a base of zero so when i use TEMP_DIR as 0xC000,I'm actually writing to 0000:0xC000 in physical memory(at least thats what i believe). I did the mapping by using the info in the intel doc to calculate the entry in the pade dir where table 2 that maps 0xC0000000+ is stored,and i came up with entry 0x300(the top 10bits of 0xC0000000).table 1 maps 1:1 so it is stored in entry 0. The addresses i write to the table entries are all ORed with 3 to set them as PRESENT|SYSTEM|WRITE pages
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problem with Paging and Mapping Code

Post by Pype.Clicker »

sorry dude, but

Code: Select all

  or ecx,dword 3          ;mark address as PRESENT|SYSTEM_PAGE|WRITEABLE
   mov [edi+ebx],dword ecx  ;write address to table[index] for mapping
only affect the TABLES. not the directory itself. If the directory's present bit is cleared, then the CPU doesn't even look at the page table.

oh, and btw,

Code: Select all

or ecx,dword 3
is so a waste of space !! just use

Code: Select all

or ecx,byte 3
which saves 3 bytes in RAM and 1 keystroke, for the very same result :)
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problem with Paging and Mapping Code

Post by Pype.Clicker »

also, afaik, 'Writable' bit is ignored while at CPL0 (unless you asked CR4 to let you have copy-on-write at kernel level, of course :) and is useless as long as 'User' bit is cleared (it is meant to say whether user code has read-only or read/write access to the page :)
Slasher

Re:Problem with Paging and Mapping Code

Post by Slasher »

You are right ;D,i didn't set the PRESENT bit for the page dir. So i've ORed 0xc000 with 3 = 0xc003 and wrote it to CR3. But it is still not working :'(
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Problem with Paging and Mapping Code

Post by Pype.Clicker »

hmm ... do you still have the "completely bogus" message ? if so, may i suggest you use Bochs's internal debugger and see if your tables and directories actually look like what you want them to ?
Slasher

Re:Problem with Paging and Mapping Code

Post by Slasher »

Sorry, the page dir (reg CR3) has no PRESENT BIT. What i meant to say was, I have set the present bits for the page tables 1 and 2 in the page dir and then wrote the address of the page dir to the CR3 reg. I'm getting
00030896768p[CPU ] >>PANIC<< exception(): 3rd (13) exception with no resolution
00030896768e[CPU ] WARNING: Any simulation after this point is completely bogus.
I've tried using the debugger but can't use it properly ???
Thanks for helping,let me try the debugger again
Slasher

Re:Problem with Paging and Mapping Code

Post by Slasher »

I'm back and still no progress??? Tried the debuger using command
xp /1024wx 0xC000
to check the content of the page dir and its showed that the first entry at 0xC000 was 0xd001 which is correct. It also showed that entry 0x300 is 0xE001 which is also correct.
I then checked the mapping for both tables at these address 0xd000 and 0xe000, and they were also correct.
So I'm really stumped! Don't understand why its not working especially since I've used paging with a 1:1 mapped memory space!
Come on all the paging Guru's on this forum, give me a hand here. Thanks
Tim

Re:Problem with Paging and Mapping Code

Post by Tim »

OK, take a step back and look at the problem.

Set up the simplest page directory/page table possible. Allocate a page table at a known address, and a page directory at a known address.

Since you're running at a physical address below 4MB, assign the first PDE to your page table.

Map all the entries in the page table. That is, set PT[ 0 ] = 7, PT[1] = 0x1007, PT[2] = 0x2007, etc. The number 7 indicates full access -- read/write, user/supervisor. Note that I'm using C-style indices here, so PT[ 0 ] is at the address of PT, PT[1] is at the address of PT + 4, PT[2] is at the address of PT + 8, and so on.

Load the page directory using MOV CR3, PD.

Enable the PG bit of CR0 by OR'ing it with 0x80000000.

JMP to an address below 4MB and hang.

If you get a triple fault, look at Bochs's log for why. If you don't, look at Bochs's log for the state of the machine -- it might not be what you expect. If you've got a non-zero base address for your code descriptor then this advice will be wrong.

After you know paging works with a jump below 4MB, extend it to work above 4MB, e.g. to 0xC0000000. But don't try to do everything in one go -- if and when it fails, you will be in the dark as there are so many things which may have gone wrong.
Slasher

Re:Problem with Paging and Mapping Code

Post by Slasher »

;DIt's working NOW!!FINALLY!! but i don't understand why. This is what i Did,
In start.asm stub I changed
1. KERNEL_MAP_ENTRY equ 0x00000300 to KERNEL_MAP_ENTRY equ 0x00000300*4 cause each entry in the page dir is 4bytes long so the 0x300th entry is at 4*0x300.
2. added code at the start to zero all the tables so that i could see which entries are changed by my mapping in the bochs debugger(thanks Pype for that suggestion)
3. I set the present bit for the 2 tables in the page dir,I forgot to do that initially :-[
Now here is what makes the difference,
initially, i was only mapping 1mb using 1:1 mapping with the first table. This table's entry in the page dir is 0,as it covers the 1st 4mb. With each entry in the table mapping 4Kb in physical memory, i was only mapping the first 256 entries (256*4096 = 1Mb) but this wasn't working.
As soon as I changed it from mapping the 1st 256 enties to mapping the 1st 512 entries (2Mb) the paging started to work! ???
I'm baffled by this,cause start.asm and the C kernel, are linked using ld with a linear address of 0xC0000000(start.asm is the entry point) and loaded at 0x200000.So by the understanding i have of paging, it should be the 2nd table i used to map 0xC0000000 into 0x200000 that covers the area that contains the code that start.asm is running. Or is it because CS has a base of 0x40200000 and start.asm instructions (before paging is enabled) have addresses starting with 0xC000xxxx which after segmentation calculations are done (CS.base + EIP.address) points to 0x0020xxxxx which is covered by my 1st table and not my 2nd one? Please someone tell me if I've finally joined the people that understand paging. Thanks Pype for responding to my questions.
:)
Tim

Re:Problem with Paging and Mapping Code

Post by Tim »

Wait... a non-zero base address? That confuses everything. Segmentation is applied on top of paging, so if you've got a base address which translates C000_0000 to 0020_0000, you'll still translate C000_0000 to 0020_0000, even after paging is enabled.

That is, with a base address of 4020_0000, the CPU won't look at the mappings for C000_000, only at the mappings for 0020_0000. Therefore I'd advice that you do a far JMP to a truly flat selector immediately after you enable paging.
Slasher

Re:Problem with Paging and Mapping Code

Post by Slasher »

yeah,I've been doing a far jump to a flat (zero based) code selector from the very start. I think I've understood the problem,i was only mapping physical 0 - 1Mb(1Mb) to linear 0 - 1Mb.The code executing(before paging is enabled) has a CS base of 0x40200000 and eip of 0xC000xxxx,CS:EIP points to physical memory 0x20xxxx. So the instruction
mov eax,cr0
or eax,0x80000000
mov cr0,eax
jmp 0x08:dword _k_main
will expect the next instruction jmp 0x80:....,after paging is enabled, to be mapped to 0x20xxxx linear which I was not doing :-[
so after I enabled paging,only pages from 0 - 1Mb were mapped(in my initial attempts) meaning that the jmp could not be found/executed. But now that I've mapped 1:1 0 - 2MB physical to linear, paging is enabled and the jmp to my kernel is found and executed.
Please comment if i've finally gotten it clear in my head. Thanks for all
Post Reply