IDT Problem: Bochs says "physical address not found"

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
ShukantPal
Posts: 23
Joined: Tue Dec 12, 2017 6:51 am
Libera.chat IRC: XtremeCoder

IDT Problem: Bochs says "physical address not found"

Post by ShukantPal »

Hi Guys,

Lately, I was developing other stuff in my kernel - but for some reasing GRUB denied loading my kernel due to relocations (the kernel relocated itself later on, and yah all kernel modules, including the main one are position-independent). Hence, I decided my kernel was complex enough, that it deserved a initializer module. The initializer module, being a static, non-relocation requiring binary, was loaded at the 1 MB mark instead of the kernel (main module, named KernelHost). It loaded the other modules, (at a physical address, but relocated at virtual addresses above 3 GB mark), relocated them, passed symbol-tables, hash-tables, string-tables, and so on to the KernelHost.

Now, everything works fine - functions are callable. I map the interrupt hooks (ISRs) to the IDT, then load it. To test whether a interrupt works:

Code: Select all

int $0x21
Boom, the kernel crashs (maybe triple faults). In Bochs, however, I get a message too that

Code: Select all

??? physical address not found # or available, don't remember, as I am on another PC 
I did the following counter-tests:

1. Called the interrupt hook from the code (there is a while loop before the IRET instruction) - yep, it works! That means it is paged, and physical address should be available.

2. I also debugged the whole IDT - everything was at its place. Entries left filled with zeros were as is - and filled entries where correct - segments, DPL, and so on.

3. Even the GDT selectors were correct - CS:0x8, DS:0x10.

What could possibly be wrong with the kernel? Note that, before the initializer module was present it was working. The kernel is now loaded at 16-MB (on the VM I am testing, but the initializer module loads it wherever it wants to). That is the only change with the module which loads the IDT (Hardware Abstraction Layer module).
nullplan
Member
Member
Posts: 1801
Joined: Wed Aug 30, 2017 8:24 am

Re: IDT Problem: Bochs says "physical address not found"

Post by nullplan »

You didn't say whether 32-bit or 64-bit, but your comment about mapping beyond 3GB makes me think it is 32-bits. In that case: Is the interrupt descriptor in the IDT a task gate? If so, is the TSS set up for that?

Other than that, I couldn't find your error message in the source.
Carpe diem!
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: IDT Problem: Bochs says "physical address not found"

Post by iansjack »

That error often results from an invalid physical address in cr3. Step through the interrupt call in the debugger and check the value in that register.
ShukantPal
Posts: 23
Joined: Tue Dec 12, 2017 6:51 am
Libera.chat IRC: XtremeCoder

Re: IDT Problem: Bochs says "physical address not found"

Post by ShukantPal »

Hello Friends,

Actually, the problem had a very different nature then all of us thought. Actually, I overwritten the 0x21 interrupt later in the code to a different function __irqCallback21 (actually HAL maps interrupts from 32 to 191 for device drivers), and then __irqCallback21 depended on some later initialization - causing a fault. I was trying to test my dummie ISR at 0x21, while the problem was at __irqCallback21.

How did I find that I overwritten the entry?

Well, I mapped a Spurious ISR at 0x21 for testing. But actually, it was also mapped at 0xFE (the APIC used it as spurious vector later) - but while debugging in Bochs, the IDT entries had different addresses. That meant that the vectors 0x21 and 0xFE did not map to the same entry.

I also found a different problem in the code too.

My initializer performed relocations on the kernel, yah. So, in the Spurious ISR, I did a test function call - but that also caused a fault (after fixing the above 0x21, 0xFE mistake). I used readelf to check the relocation on that function call - PC32. I checked my PC32 relocation - everything was right, wait. In PC32 relocation, you subtract the address where the relocation was occuring. But my initializer did that - except the physical address. That caused the whole problem - it was in physical memory, but was being relocated for virtual memory, so I fixed that to subtract the virtual address of the relocation patch.

Thanks, everyone! My updated code will be available at GitHub - if you see the new Initializer folder, then it is the patched version (search Silcos-Kernel to get it)!!!
Post Reply