My kernel is loaded by Limine in 64-bit mode. IDT is set up, software interrupts (`int $0x32`) work. PIC is initialized, IRQ0 unmasked, PIT configured. However, hardware interrupts from PIT never arrive.
What works
- IDT loaded (verified via SIDT)
- Software interrupt `int $0x32` triggers the handler (prints characters)
- PIT counter changes (verified via `inb`)
- CPL = 0 (Ring 0)
What doesn't work
- Hardware interrupts from PIT never arrive
- Tried disabling APIC with `-cpu qemu64,-apic` — didn't help
Code (simplified)
IDT:
Code: Select all
void idt_set_gate(uint8_t vector, void *handler, uint8_t type_attr) {
uint64_t addr = (uint64_t)handler;
idt[vector].base_low = addr & 0xFFFF;
idt[vector].selector = 0x28; // CS=0x28 from GDT. This is the correct selector that has determined itself
idt[vector].type_attr = type_attr;
idt[vector].base_mid = (addr >> 16) & 0xFFFF;
idt[vector].base_high = (addr >> 32) & 0xFFFFFFFF;
}Code: Select all
outb(0x20, 0x11);
outb(0xA0, 0x11);
outb(0x21, 0x20);
outb(0xA1, 0x28);
outb(0x21, 0x04);
outb(0xA1, 0x02);
outb(0x21, 0x01);
outb(0xA1, 0x01);
outb(0x21, 0xFC); // IRQ0 and IRQ1 unmasked
outb(0xA1, 0xFF);Code: Select all
outb(0x43, 0x34); // mode 2
outb(0x40, divisor & 0xFF);
outb(0x40, (divisor >> 8) & 0xFF);QEMU 10.0.7
Bootloader: Limine (64-bit)
Launch command: qemu-system-x86_64 -cdrom template-x86_64.iso -debugcon stdio
Questions
How do I determine which I/O APIC input the PIT is connected to?
Do I need to completely disable PIC if I want to use APIC?
Is there a simple way to make PIT work with APIC without ACPI?
Should I just switch to the Local APIC Timer instead?
Notes:
I used a translator, so there may be mistakes. I'm new to OSDev and this is my first kernel that got this far. Any help is appreciated!
Full code on https://github.com/Cubik-Cubovich/CAMFOS
