OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 12:02 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Clearing interrupts causes a crash
PostPosted: Fri Apr 09, 2021 12:26 pm 
Offline

Joined: Fri Apr 09, 2021 11:53 am
Posts: 2
I'm following the GDT Tutorial page from the wiki and appear to have gotten my descriptor table up and working, but the one oddity I'm running into is that clearing interrupts with cli causes an instant crash.

My kernel is basically the same as what's in the bare bones page. I'm running it under Hyper-V. It starts from GRUB. It sets up a stack in the .bss section, then transfers control to C code. The C code initialises VGA and prints some debug output so I can see the state of the registers and segment addresses. I then build 6 GDT entries: a null entry, code and data segments for DLP0 and DLP3, and a TSS entry (which I'm not using for anything just yet).

I wanted to specify separate code and data segments for ring 0, so I could get separation of executable pages and read/write pages, but I haven't quite figured out the linker scripts to ensure that everything goes into the right places for that. So for now my DLP0 code and data entries point at 0x00000000, with the code entry being 0x0FFFFFFF long and the data entry being 0x1FFFFFFF long. The .data and .bss sections get loaded at 0x10000000, so they're outside of the executable segment.

I'm applying the GDT as follows:

Code:
apply_gdt:
    mov eax, dword ptr [esp + 4]
    mov dword ptr [gdtr + 2], eax
    mov ax, word ptr [esp + 8]
    mov word ptr [gdtr], ax
    lgdt [gdtr]
    ret

reload_gdt:
    jmp 0x08:reload_CS
reload_CS:
    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    ret


This is called as follows:

Code:
void gdt_apply(void)
{
    apply_gdt(KernelGDT, sizeof(KernelGDT) - 1);
    reload_gdt();
}


(side note: in the wiki, the example says that the code assumes it's being called with sizeof(GDT), but as I understand it the size should be one less than that due to the way that the size field works)

This appears to work fine. Dumping the segment registers shows that they've changed over. Code continues to execute just fine. I suspect that it's not good practice to return back to C between applying the GDT and reloading the segment registers, but I don't think it causes any issues for now based on the disassembly I've looked at.

However, the wiki page also says that interrupts should be cleared before applying the GDT. I can see why this would be important - you don't want interrupts landing mid-way through your segment reload and messing everything up. So I used the cli/sti mnemonics to clear interrupts during this process, and it crashes immediately - I presume with a triple fault.

To rule things out, I added a cli followed by sti in the _start assembly, way before I even get close to setting up the GDT. This also causes an immediate crash.

I'm a bit confused as to why this occurs. Reading the instruction reference for cli, specifically the cases in which a GPF can be raised, I suspect I might be missing a key detail about protected-mode virtual interrupts, which I'm not particularly familiar with. What's going on here?


Top
 Profile  
 
 Post subject: Re: Clearing interrupts causes a crash
PostPosted: Sat Apr 10, 2021 6:53 am 
Offline
Member
Member

Joined: Tue Apr 03, 2018 2:44 am
Posts: 401
gsuberland wrote:
So I used the cli/sti mnemonics to clear interrupts during this process, and it crashes immediately - I presume with a triple fault.

To rule things out, I added a cli followed by sti in the _start assembly, way before I even get close to setting up the GDT. This also causes an immediate crash.

I'm a bit confused as to why this occurs. Reading the instruction reference for cli, specifically the cases in which a GPF can be raised, I suspect I might be missing a key detail about protected-mode virtual interrupts, which I'm not particularly familiar with. What's going on here?


Are you using cli and sti? In what order, and do you know which one triggers the fault?

I suspect it's actually sti that is triggering the fault, as that enables interrupts, and it's probably an incoming interrupt that is causing the crash (because it doesn't sound like you've set up the IDT yet.) cli just clears the interrupt flag, disabling interrupts.

If it is cli that is causing the crash, then it's probably a GPF, which will occur if you're not running in a privileged ring. When you set up your protected mode environment, did you jump to the RING 0 code segment or the RING 3 code segment?


Top
 Profile  
 
 Post subject: Re: Enabling interrupts causes a crash
PostPosted: Sat Apr 10, 2021 9:07 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
You need to set up an IDT, and interrupt handlers, for any potential interrupt before enabling interrupts. It's also sensible to set up basic exception handlers.

My guess would be a timer interrupt.


Top
 Profile  
 
 Post subject: Re: Clearing interrupts causes a crash
PostPosted: Sat Apr 10, 2021 10:08 am 
Offline

Joined: Fri Apr 09, 2021 11:53 am
Posts: 2
Thanks all. I figured this out last night while the post was awaiting approval. It was indeed that I was hitting sti before I had an IDT set up - I hadn't considered that GRUB would start the kernel with interrupts disabled, but of course that's exactly what was happening.

The critical detail that allowed me to figure it out was switching to qemu and using the debugging logs. I could see that cli and sti were being executed, but the instruction immediately afterwards, at the faulting IP, was not the next one from my function. I quickly realised it must be jumping to a garbage ISR, and the qemu debug logs showed that there was indeed an interrupt being fired.

This is solved, and I now have a working IDT and ISRs set up! :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], SemrushBot [Bot] and 81 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group