interrupt fails, after enable paging

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
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

interrupt fails, after enable paging

Post by blackoil »

Hi,

after move kernel to virtual address 0x80000000+, and clear low half PD,
I got page fault, when interrupt fires. If I don't clear the low half PD, it runs well. From CR2, It seems something accessed low half space.

I load IDT before initial identity paging, IDTR base address is linear addr, IDT descriptor offset is virtual addr. keyboard ISR is set to "jmp $". when I press a key, It didn't go to KB ISR, just reset.


00067001000i[CPU0 ] CPU is in protected mode (active)
00067001000i[CPU0 ] CS.d_b = 32 bit
00067001000i[CPU0 ] SS.d_b = 32 bit
00067001000i[CPU0 ] EFER = 0x00000000
00067001000i[CPU0 ] | RAX=00000000000007ff RBX=0000000000001000
00067001000i[CPU0 ] | RCX=0000000000000200 RDX=00000000000003d5
00067001000i[CPU0 ] | RSP=000000008009ffff RBP=00000000800087f8
00067001000i[CPU0 ] | RSI=00000000000e0000 RDI=000000008000ef12
00067001000i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00067001000i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00067001000i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00067001000i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00067001000i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf SF zf af PF cf
00067001000i[CPU0 ] | SEG selector base limit G D
00067001000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00067001000i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
00067001000i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00067001000i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00067001000i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00067001000i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00067001000i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00067001000i[CPU0 ] | MSR_FS_BASE:0000000000000000
00067001000i[CPU0 ] | MSR_GS_BASE:0000000000000000
00067001000i[CPU0 ] | RIP=0000000080008327 (0000000080008327)
00067001000i[CPU0 ] | CR0=0xe0000011 CR2=0x0000000000007feb
00067001000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00067001000i[CPU0 ] 0x0000000080008327>> mov byte ptr ds:0x8000eced, 0x00 : C605EDEC008000
00067001000e[CPU0 ] exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting
00067001000i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: interrupt fails, after enable paging

Post by NickJohnson »

Where does your GDT pointer point to: higher or lower memory? I had this problem, and it turned out that the GDT was mapped in lower memory, before I enabled paging. When the interrupt reloaded the segment descriptors, the processor page faulted where it thought the GDT was. To fix it, just set the GDT pointer after enabling paging.

Edit: Oh wait, you also have that problem with your IDT pointer - it needs to be a virtual address. That would cause a similar problem. Make sure to load it after you enable paging instead of before.
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

Re: interrupt fails, after enable paging

Post by blackoil »

GDT, IDT, TSS are all in low memory.
IDT descriptors are all set to virtual address, before enable paging.

And I checked the CR2 address (0x7FEB) in my os binary, it happens to 9th Interrupt.

I will try to reload GDTR
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

Re: interrupt fails, after enable paging

Post by blackoil »

ok, now
I modified the GDT,IDT .base address to virtual addr, it works now

Code: Select all

				add [0x80000000+GDT.base],dword 0x80000000
				add [0x80000000+IDT.base],dword 0x80000000
				lgdt [0x80000000+GDT]
				lidt [0x80000000+IDT]
for basic paging-enable initialization, I use following steps.

initGDT
enter pmode
Paging
setup GDT,IDT,TSS
User avatar
kop99
Member
Member
Posts: 120
Joined: Fri May 15, 2009 2:58 am

Re: interrupt fails, after enable paging

Post by kop99 »

Code: Select all

00067001000i[CPU0 ] | CR0=0xe0000011 CR2=0x0000000000007feb
00067001000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
there is page enable bit in cr0.
Then cr3 register is all zero...
did you do that?
Make sure page directory's position...
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

Re: interrupt fails, after enable paging

Post by blackoil »

yes, kop99

I place page directory in 0x00000000, so CR3 is 0x00000000
initial page table in 0x00001000
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: interrupt fails, after enable paging

Post by pcmattman »

I modified the GDT,IDT .base address to virtual addr, it works now
According to the Intel manuals (3A, 2-16), the GDT base is a linear address. When paging is active, linear addresses go through the MMU (3A, 3-7, linear address space split into pages with page-level protection facilities).

Also, you may not want to overwrite the memory at address 0x0 without saving it first. If you want to run virtual 8086 mode tasks in the future you need the IVT intact.
Last edited by pcmattman on Sat May 30, 2009 12:42 am, edited 1 time in total.
blackoil
Member
Member
Posts: 146
Joined: Mon Feb 12, 2007 4:45 am

Re: interrupt fails, after enable paging

Post by blackoil »

yes, GDTR, IDTR both contain linear addr, I recheck the manual

lgdt [GDT]

before paging enable, GDT is linear address itself.
after paging enable, GDT is virtual address, MMU calculates the final linear address.

I don't support v8086 mode, so I place PD there.
Post Reply