OS Development Notes: Legacies
2023-12-10 | osdev x86 acpi apic interruptsForeword
These notes are more to gather research on how to get to the next step: getting input. Code are in progress and will be committed for another article.
Legacies
When choosing x86_64
as the platform to develop on first, there is a lot of legacies from
32-bit to 16-bit implementations, primarily from Intel, who produced the first processor 8088
to give birth to the x86
family of processors that share much from the first instruction set.
This also gave birth to many different instruction sets as IA-32
, Intel's big dream of continuing 32-bit,
while AMD was working on their 64-bit with AMD64
that is the x86_64
or x64
used today.
Interrupts
One of these legacies is the Interrupt Descriptor Table
(IDT) that is back from the IA-32
times.
Just like the Global Descriptor Table
(GDT) it shares a structure of handling descriptions of how a system
should behave in general.
The IDT was first used with the common Intel chip at the time, the 8259 PIC Programmable Interrupt Controller
,
for handling incoming interrupts and sending them to the CPU by services, setup in beforehand. There was only 8 interrupts.
At some point, it was necessary to add another PIC, giving access to cascading interrupts and handling more of them at the time.
But 15 was not enough either, and also it could only handle a single processor at the time. Intel came up with a new version
the Advanced Programmable Interrupt Controller
(APIC) that was divied into Local APICs
(LAPICs) for each core and I/O APICs
(IOAPICs)
for handling hardware interrupts, which is CPU agnostic. Typically a x86_64
only has one IOAPIC, but these days there will
be several LAPICs, handling the several processors independently (called PerCPU).
Each LAPIC has a Local Vector Table
(LVT) that translates events into a interrupt vector. It communicates through Model Specific Registers
,
a new collection of registers since Pentium 6, especially on a x2APIC
system, which superseeded the xAPIC
variant in 2008.
While the x2APIC
cleaned up in some of the legacies, new ideas came along joining IOAPIC
to fight the already tight space for interrupts.
The PCI bus and especially now the PCI-Express bus became much more used, and wanted to chime in with their Message Signaled Interrupts
(MSI).
MSI allowed up to 32 interrupt allocations per device, and the newer and now generally used MSI-X allows up to 2048 interrupt allocations.
IOAPIC was a big step in faster handling of interrupts, but MSI-X is even faster, but at the cost of a lot of interrupt allocation. How are the LAPICs going to handle them?
The old with the new
First of all everything still has to go through IDT, which has a limit of 255, and quite a few is already used for system specific handling, like exceptions (divide by zero, page errors...).