Hi,
simeonz wrote:Brendan wrote:It's not that simple - the BIOS uses PIC (where there's 15 IRQs and most are reserved for legacy stuff), which means that most PCI devices end up sharing PIC IRQs, which means you can't replace one IRQ for one device without breaking other devices that share that IRQ.
Actually, as
alexfru already pointed out, the BIOS clock update (and the aforementioned FDD motor function) do apparently use interrupt vector 0x08. Which means that the on-board firmware (may be in accordance to some authority or another) is free to install its own handler at this vector. It also means that the bootloader/OS cannot install their own ISR there without chaining to the default handler, and cannot remap the PIC vector range, unless they are prepared to break certain BIOS functions.
It depends too much on the specific case (there's no simple/generic answer).
For the PIC chips; if you change the PICs' configuration (e.g. so that "IRQ0 -> interrupt 0x20" and "IRQ8 -> interrupt 0x28") you risk losing any IRQs that occur while you're reconfiguring the PIC chips (which can cause "who knows what" to break due to lost IRQs if the timing happens to be unfortunate) and then you'd have to uphold the BIOS's expectations by making sure that the BIOS IRQ handler is called for all IRQs (e.g. interrupt 0x08 is called when IRQ0 occurs, interrupt 0x09 is called when IRQ1 occurs, etc) and by allowing BIOS to continue sending the EOI. It's mostly a pointless waste of time trying to bother (extra risk with no benefit).
simeonz wrote:Which still leaves the question, are there other such vectors, or is the timer one the only one?
There's no guarantee that the BIOS uses IRQ0 for floppy motor control (e.g. it could use IRQ8 - the RTC's IRQ instead). There's no guarantee that IRQ0, IRQ1, IRQ3 and IRQ4 aren't being used by BIOS as part of a convoluted legacy emulation scheme (e.g. SMM being used to make HPET emulate a PIT chip that doesn't exist, or make a USB device emulate a keyboard or mouse that doesn't exist, or make a network card emulate a serial port that doesn't exist). There's no guarantee that one of the IRQs (often IRQ9) isn't used for power management stuff. There's no guarantee that IRQs 3, 4, 5, 6, 7, 9, 10, 11, 12, 14 or 15 aren't being used by multiple PCI devices in the background. You can expect that IRQ13 is used for FPU errors.
Essentially; you have to assume that BIOS may be using any/all IRQs for something, because there's no guarantee that it's not.
simeonz wrote:Again, what prevents a SCSI option ROM or Boot Connection Vector (if I have understood the nomenclature right) from overriding any number of interrupt vectors.
Nothing prevents a SCSI option ROM from overriding anything; other than needing to uphold the rest of the BIOS's expectations and needing to uphold software's expectations. I would expect that some SCSI controller option ROMs hook "int 0x15" (to hide any RAM it borrows) and I'd expect all of them would hook "int 0x13" to make disk services work for SCSI, where it would pass control back to the BIOS' original "int 0x13" handler if the device isn't a SCSI device so that it can avoid breaking things like floppy or USB or ATA/SATA (possibly including modifying the "device numbers" so that when you read/write sectors on device 0x82 the SCSI ROM decides it's not a SCSI device and tells the original BIOS to read/write the sectors from device 0x80 instead of device 0x82). Note that I have heard a few horror stories (for SCSI controllers and network cards) that usually start with something like "this controller doesn't use IO ports and the memory mapped IO area that the driver needs to access is outside the 1 MiB area that real mode can access" and then becomes a massive pile of ugly hacks (e.g. the option ROMs for multiple NICs switch between real mode and protected mode).
simeonz wrote:What is the right conduct for a DOS-like OS or bootloader to install its own ISR?
The right conduct for a DOS-like OS is to go back 30 years (to the 1980s) and achieve market dominance while being laughed at by all real OSs from the same era or earlier (Unix, VMS, etc) until it dies from embarrassment in the 1990s. This is very important because in the early years (before there was much hardware variety - SATA, USB, mouse, etc) it allows the DOS-like OS to avoid touching any hardware itself (just relying on BIOS for low-level hardware access); and then in the later years (as new types of hardware are invented) it forces hardware and ROM manufacturers (due to market dominance) to implement large quantities of ugly hacks to work-around the fact that the OS is a pathetic joke.
As far as I'm concerned; the right conduct for a boot loader is to use the firmware to prepare for whatever happens next (starting kernel, or starting whatever is between boot loader and kernel, possibly including loading an "initial RAM disk" or something into RAM so that whatever happens next doesn't need any disk or network IO), without having any reason to install any ISRs if the firmware happens to be BIOS; such that everything that happens after the boot loader is finished (after boot loader has called "exitBootServices" on UEFI, and after there's no longer any reason to uphold the firmware's expectations because the OS has officially taking control of all hardware) has no reason to know or care what the firmware was.
simeonz wrote:Brendan wrote:Think of it like a kitten - you can pat it, you can feed it, etc, and that's fine - everything works because everything is contained within the kitten's skin. However; if you try to rip out it's left lung and install an alternative left lung then you can expect various problems (dead kitten) because inside that "self contained skin" there's parts that rely on each other (inter-dependencies).
Yes, but I think you are referring to BIOS software interrupt vectors. Or may be not?
I'm talking about:
- The contents of various areas of memory that the BIOS may rely on ("BIOS Data area" at 0x00000000, the EBDA, whatever might be in the option ROM area, and any areas reserved in the memory map for ACPI or for anything else)
- The state of all hardware; including the chipset itself (memory controller, etc), the PIC chips and IO APICs, PCI configuration space, disk controllers, network controllers, USB controllers, etc.
- Anything that might be involved in legacy emulation, power management or hardware error reporting (ECC, thermal and current overloads, etc)
- Anything that might be involved in device insertion or removal (hot-plug PCI, hot-plug SATA, hot-plug memory, ..)
simeonz wrote:I am talking about the PIC triggered hardware interrupt vectors. My question is whether those are under the discretion of the OS/bootloader, assuming that it wants to continue to use BIOS services, or are those supposed to be chained to their default BIOS implementations in all cases.
I don't know how to make this clearer. Except for a few ugly/annoying/unwanted exceptions (ACPI's AML, SMM, UEFI run-time services maybe), either:
- the firmware has ownership of all hardware (and the OS doesn't touch any hardware directly), or
- the OS has ownership of all hardware (and ensures that the firmware doesn't touch any hardware directly), or
- it's a festering nightmare that needs to die
simeonz wrote:And also, even if the device ROMs or motherboard BIOSes do not (are required not to) install ISRs for hardware, whether parasitic hardware interrupts are possible side-effect from calling the BIOS services. Would, say DOS, be required to always chain ISRs to the default handlers that it finds? Can using int 13h result in calls to ISR 14 and 15 as a side effect? This is the nature of my inquiry.
It's probably best to think of MS-DOS as "a set of BIOS extensions with a shell slapped on top" (and stop thinking of it as an OS). Because it's mostly BIOS extensions it follows similar rules to other BIOS extensions (e.g. option ROMs) in that it can do whatever it likes as long as it upholds the rest of the BIOS's expectations and upholds software's expectations. This causes a need for a huge amount of ugly hacks and work-arounds and sacrifices (to uphold those expectations) where (as hardware evolved and new features are added - e.g. 32-bit, SMP/multi-CPU, APICs, ...) that "huge amount" grows over time. That huge amount became "too much to be sustainable" decades ago.
Note: Microsoft had to have known DOS was a dead end in the late 1980s, but they couldn't suddenly announce "DOS is dead, stop using it immediately" without losing all their existing customers, their market share and their monopoly. They needed to ween people away from DOS (and towards the Windows NT kernel and a more modern API) slowly (including using "Windows 9x" as a temporary bridge between the past that had to die and a sustainable future). It's this "slow weening to preserve Microsoft's market share/profits" that is the reason why DOS took a decade longer to die than it should have.
simeonz wrote:I don't know about stock motherboard firmware, but SeaBIOS apparently works under IF=0 most of the time. It reenables it when it is about to wait, and disables it again on each poll iteration, or something of the sorts. However, it is a rather complex BIOS, because they have implemented something like a scheduler, which allows interleaved processing in the pre-boot stage. After the handoff to the bootloader, I am not sure - are the service calls busy waiting or do they use HLT when possible (thus actively relying on device interrupts.) I haven't checked.
SeaBIOS is open source; which literally means "let's get some volunteers that have no clue what they're doing and let them slap together something that's barely good enough to start a modern OS (that doesn't have a reason to care about the BIOS for more than about 3 microseconds after power on) and doesn't have to care about thousands of different devices that can't be plugged into the computer because Qemu doesn't emulate them". There's no reason to care what SeaBIOS does - to ensure that there's no problem for any computer's BIOS you'd have to examine the code for several thousand different BIOSs (or alternatively, refuse to rely on potentially dodgy assumptions because you aren't able to ensure there's no problem for any computer's BIOS).
simeonz wrote:Brendan wrote:One of the things I like about UEFI is "ExitBootServices" - a clear point where ownership/control of all the hardware passes from firmware to OS. This is something that BIOS desperately lacks; but that doesn't mean you shouldn't follow the same principle and define a clear "point where ownership/control of all hardware is transferred from firmware to OS" of your own.
I see. This is why I thought that UEFI would program and use the IDT, PIC/APIC more aggressively. At least in the more recent specifications where it also offers asynchronous I/O, I figured that it might have introduced PIC/APIC interfaces for interrupt-based I/O completion. But from what I understand so far, they chose the minimalist approach, even if slightly improved - i.e. periodic timed polling.
UEFI is supposed to be a portable thing (with no platform specific requirements). Originally it was implemented for Itanium (which doesn't have "80x86 PIC chips" or "80x86 IO APICs"); then it made it's way to 80x86 PCs; and now it's being used for ARM servers (which don't have "80x86 PIC chips" or "80x86 IO APICs").
For 80x86 PCs alone; PIC chips are deprecated (superseded by IO APICs about 15 years ago) and as soon as UEFI finishes replacing BIOS (and all the "compatibility requirements" disappear) I'd expect the PIC to no longer exist.
Note: There's been a "computer does/doesn't have PIC chips" flag in ACPI's tables for as long as I can remember - they're just waiting for hardware to catch up). For IO APICs; PCI devices moved to MSI (Message Signalled Interrupts) as an optional thing in PCI 2.2 (in 1998), and made it mandatory for PCI express (in 2004). In 10 years time I wouldn't be too surprised if IO APIC ceases to exist too (there's a very small number of devices that aren't already able to use MSI and haven't been superseded yet - the RTC chip is the only one I can think of).
Cheers,
Brendan