Page 2 of 2

Re: Crash after loading GDT and flushing registers

Posted: Tue Sep 14, 2021 1:38 pm
by nexos
You're still violating the ABI :) . You should be doing this:

Code: Select all

mov edx, dword [esp+4]
Right now, you're accessing the function return address (not the first parameter) if you just did

Code: Select all

pop edx

Re: Crash after loading GDT and flushing registers

Posted: Tue Sep 14, 2021 1:53 pm
by YDeeps1
nexos wrote:You're still violating the ABI :) . You should be doing this:

Code: Select all

mov edx, dword [esp+4]
Right now, you're accessing the function return address (not the first parameter) if you just did

Code: Select all

pop edx
I am aware! Popped was the wrong word to use :lol: I was still accessing the parameter; not the return address. Thanks anyways.

Re: Crash after loading GDT and flushing registers

Posted: Tue Sep 14, 2021 3:55 pm
by YDeeps1
I have done a little more debugging and I found QEMU very helpful.

Debugging by launching the VM with the debug flag set to log interrupts, the first interrupt appears to be a general protection fault (0xd - 13):

Code: Select all

check_exception old: 0xffffffff new 0xd
     0: v=0d e=0010 i=0 cpl=0 IP=0008:0010001b pc=0010001b SP=0010:00301fb4 env->regs[R_EAX]=00000010
Update - After sacrificing some of my sleep I have finally figured out the problem! My function which deals with split bits is incorrect and produces incorrect bits so I have converted my entry structure into a little bitfield and simply opted into hard coding the bits with a little assistance of a binary to hex converter and now my table works.

Code: Select all

GDT DefaultGDT = {
    {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
    {0x8000, 0x0, 0x0, 0x9A, 0x0, 0xC, 0x0},
    {0x8000, 0x0, 0x0, 0x92, 0x0, 0xC, 0x0},
    {0x8000, 0x0, 0x0, 0xFA, 0x0, 0xC, 0x0},
    {0x8000, 0x0, 0x0, 0xF2, 0x0, 0xC, 0x0}
};
And have also fixed up my far jump with the help of the wiki.

Thank you everyone for your contributions!

Re: Crash after loading GDT and flushing registers

Posted: Tue Sep 14, 2021 7:28 pm
by Octocontrabass
YDeeps1 wrote:I have also logged the address of the GDT offset + size table address (decimal 18874372) which matches up with the EDX register, removing some possibilities.
Why is this address 17 megabytes above the start of your kernel? How big is your kernel, anyway?

Re: Crash after loading GDT and flushing registers

Posted: Wed Sep 15, 2021 12:31 am
by YDeeps1
Octocontrabass wrote:
YDeeps1 wrote:I have also logged the address of the GDT offset + size table address (decimal 18874372) which matches up with the EDX register, removing some possibilities.
Why is this address 17 megabytes above the start of your kernel? How big is your kernel, anyway?
I was about to answer that. My kernel is actually only a few kilobytes maximum but to avoid any possibility such as my stack doing something to the GDT like accidentally overwriting it due to some other critical mistake I have instead stored it in my heap which I set to be about 20M above to remove this doubt.

Re: Crash after loading GDT and flushing registers

Posted: Wed Sep 15, 2021 8:49 am
by Octocontrabass
That's the address of your GDT descriptor, not your GDT. According to the register dump from earlier, your GDT lives in the .data section near your stack.

And anyway, you don't need the GDT descriptor after you've copied it into the GDTR with LGDT. You could allocate it on the stack instead.

Re: Crash after loading GDT and flushing registers

Posted: Wed Sep 15, 2021 10:13 am
by nullplan
Small function to load GDT with GDTR on stack:

Code: Select all

;C interface: void load_gdt(const void *gdt, size_t sz);
global load_gdt
load_gdt:
  sub esp, 8
  mov eax, [esp+12]
  mov cx, [esp+16] ; if this exceeds 2 bytes, you have a problem, anyway
  dec cx
  mov [esp+4], eax
  mov [esp+2], cx
  lgdt [esp+2]
  add esp, 8
  ret