Quote:
You can fix it by adding code right after you load the GDTR to also load CS, DS, ES, SS, and probably FS and GS.
This worked, thank you so much for the help!
I should've noticed the reply and asked about it earlier, as I was about to quit after one month of no progress.
At least I got to fix a few minor issues, change stubs, and experiment with different iterations. Just need to clean it up and finally move forward.
For anyone having a similar issue, I will leave the fix below. Keep in mind that the code changed a bit and has a different stub and setup. This change fixes the main issue in the github version, for the test in boot.cpp. Keep in mind that in the github version, Pit was not using the stub yet so it requires more changes for that to work.
The fix is the following:
1 - Change stub code to bypass registers parameter on return, and push/pop segment registers correctly (posted previously).
2 - Change the gdt load to a function in assembly that load gdtr, and loads the registers:
Code:
.global gdt_load
gdt_load:
mov 4(%esp), %eax
lgdt (%eax)
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
ljmp $0x8, $1f
1: ret
3 - Call this new function in my class:
Code:
extern "C" void gdt_load(uintptr_t p);
void GDT::Setup()
{
... // setup descriptors
gdt_load((uintptr_t)&m_gdtr);
}
In theory, the assembly function can be converted to inline assembly. However, and I don't know why, it wasn't working when called inside a member function. It worked fine in a normal free function, though.
Thank you so much once again. I wouldn't have found it without your help.