OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 2:39 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: CPU Triple Faults when booting from drive instead of cdrom
PostPosted: Thu Nov 03, 2022 2:27 am 
Offline

Joined: Mon Aug 15, 2022 12:30 pm
Posts: 18
Update: I have solved the issue simply by zeroing the IDT before initializing the page:

Code:
    memset((void*)idtr.offset, 0, 256 * sizeof(struct idtdescentry));


But, as long as the previous code yielded a page fault (or a double fault), as the idt entry
was correct, it shouldn't matter that the page has trash somewhere else. As every entry is
initialiced by the default handler, I'm not sure why this "fixed" the problem.

I migrate my original question to: This is weird, do you see anything wrong here?

Original question:

Hello everyone.

I'm facing trouble with interrupts on my kernel. I'm forcing a general protection fault to
test interrupt handling works.

Code:
   
    void * target = request_page(); //Request a physical page with page frame allocator
    memset(target, 0, 4096);
    map_memory((void*)0xffffffffdeadb000, target); //Map it to the address

    uint64_t* ptr1 = (uint64_t*)0xffffffffdeadb000;   
    PAGE_RESTRICT_WRITE((void*)ptr1); //Clear writable bit in page table

    *ptr1 = 0xdeadbeef;


When I create an iso with xorriso and boot it with qemu by doing:
Code:
qemu-system-x86_64 -cpu qemu64 -d cpu_reset -machine q35 -m 512 -boot d -cdrom ./image.iso


Everything works as a charm.

But if I create a limine compatible .img and run it like:
Code:
qemu-system-x86_64 -cpu qemu64 -d cpu_reset -machine q35 -m 512 -boot d -cdrom ./test/useless.iso -drive if=pflash,format=raw,unit=0,file=./OVMFbin/OVMF_CODE-pure-efi.fd,readonly=on -drive if=pflash,format=raw,unit=1,file=./OVMFbin/OVMF_VARS-pure-efi.fd -net none -drive file=./image.img

The cpu triple faults.

It is mandatory to point out that some interrupts work fine, i can handle keyboard input, pit, mouse, divbyzero, etc just fine. But the PageFault and general protection fault handlers
don't seem to work.

My initialization code:

Code:
struct idtr idtr;

void set_idt_gate(uint64_t handler, uint8_t entry_offset, uint8_t type_attr, uint8_t selector) {
    struct idtdescentry* interrupt = (struct idtdescentry*)(idtr.offset + entry_offset * sizeof(struct idtdescentry));
    set_offset(interrupt, handler);
    interrupt->type_attr = type_attr;
    interrupt->selector = selector;
}

void init_interrupts(uint8_t pit_disable) {

    __asm__("cli");

    idtr.limit = 0x0FFF;
    idtr.offset = (uint64_t)request_page(); //Request physical page

    for (int i = 0; i < 256; i++) {
        set_idt_gate((uint64_t)UncaughtInt_Handler, i, IDT_TA_InterruptGate, 0x28);
    }

    set_idt_gate((uint64_t)PageFault_Handler,   0xE,    IDT_TA_InterruptGate, 0x28);
    set_idt_gate((uint64_t)DoubleFault_Handler, 0x8,    IDT_TA_InterruptGate, 0x28);
    set_idt_gate((uint64_t)GPFault_Handler,     0xD,    IDT_TA_InterruptGate, 0x28);
    set_idt_gate((uint64_t)KeyboardInt_Handler, 0x21,   IDT_TA_InterruptGate, 0x28);
    set_idt_gate((uint64_t)MouseInt_Handler,    0x2C,   IDT_TA_InterruptGate, 0x28);
    set_idt_gate((uint64_t)PitInt_Handler,      0x20,   IDT_TA_InterruptGate, 0x28);
    set_idt_gate((uint64_t)DivByZero_Handler,   0x0,    IDT_TA_InterruptGate, 0x28);
   


    __asm__("lidt %0" : : "m"(idtr));

    remap_pic();

    init_keyboard();

    outb(PIC1_DATA, 0xf8 + pit_disable); //PIT IS DISABLED
    outb(PIC2_DATA, 0xef);

    __asm__("sti");

}


Every handler but pit,kb and mouse is just printing its name and halting.

Code:
__attribute__((interrupt)) void UncaughtInt_Handler(struct interrupt_frame* frame) {
    dbg_print("UncaughtInt_Handler\n");
    (void)frame;
    while(1);
}


Any idea on what may be going on here?

P.S. The entire code is available here: https://github.com/TretornESP/bloodmoon

P.S.v2. I can't log interrupts with qemu's
Code:
-d int
as booting with OVMF and Limine generate too many interrupts, slowing the program down
to the point where it will never boot. cpu_reset just tells me what I was already expecting (A triple fault on the write operation).

Code:
Triple fault
CPU Reset (CPU 0)
RAX=00000000deadbeef RBX=0000000000000000 RCX=0000000000a78000 RDX=0000000000a77001
RSI=0000000000000000 RDI=ffffffff8000c93b RBP=0000000000a77000 RSP=ffff80001d98aff0
R8 =00000000000000f5 R9 =ffffffffdeadb000 R10=000000001fe13200 R11=0000000000000009
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=ffffffff8000bb33 RFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0030 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
CS =0028 0000000000000000 00000000 00209a00 DPL=0 CS64 [-R-]
SS =0030 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
DS =0030 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
FS =0030 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
GS =0030 0000000000000000 00000000 00009300 DPL=0 DS   [-WA]
LDT=0000 0000000000000000 00000000 00008200 DPL=0 LDT
TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy
GDT=     ffff80001fee7000 00000037
IDT=     0000000000a09000 00000fff
CR0=80010011 CR2=0000000000000044 CR3=000000001d97a000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000018 CCD=0000000000a77001 CCO=LOGICQ
EFER=0000000000000d00
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=0000000000000000 0000000000000000 XMM01=0000000000000000 0000000000000000
XMM02=0000000000000000 0000000000000000 XMM03=0000000000000000 0000000000000000
XMM04=0000000000000000 0000000000000000 XMM05=0000000000000000 0000000000000000
XMM06=0000000000000000 0000000000000000 XMM07=0000000000000000 0000000000000000
XMM08=0000000000000000 0000000000000000 XMM09=0000000000000000 0000000000000000
XMM10=0000000000000000 0000000000000000 XMM11=0000000000000000 0000000000000000
XMM12=0000000000000000 0000000000000000 XMM13=0000000000000000 0000000000000000
XMM14=0000000000000000 0000000000000000 XMM15=0000000000000000 0000000000000000


Top
 Profile  
 
 Post subject: Re: CPU Triple Faults when booting from drive instead of cdr
PostPosted: Thu Nov 03, 2022 10:51 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
tretornesp wrote:
I migrate my original question to: This is weird, do you see anything wrong here?

It looks like your set_idt_gate() function doesn't set the entire descriptor.


Top
 Profile  
 
 Post subject: Re: CPU Triple Faults when booting from drive instead of cdr
PostPosted: Sat Nov 05, 2022 9:38 am 
Offline

Joined: Mon Aug 15, 2022 12:30 pm
Posts: 18
Quote:
It looks like your set_idt_gate() function doesn't set the entire descriptor.


You are absolutely right. It assumes zeroed memory.

After spending too much time with a piece of code I usually start making wrong assumptions about it...

Thank you so much.


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: DotBot [Bot] and 49 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