Matthew Garrett (mjg59) wrote,
Matthew Garrett

Why Linux claims to be Windows

Section 5.7.2 of the ACPI specification provides for a method called _OSI. Platform firmware can query for various interfaces, which allow it to tweak its behaviour depending on the interfaces that the OS supports. Linux claims to support the following interfaces:
  • Windows 2000
  • Windows 2001
  • Windows 2001 SP1
  • Windows 2001 SP2
  • Windows 2001.1
  • Windows 2001.1 SP1
  • Windows 2006
which all correspond (unsurprisingly) to different versions of Windows. Linux used to be in there, but was removed for reasons I'll get into later.

The typical way in which this feature is used by a platform is by querying each of the interfaces in turn, starting with the most recent a firmware is aware of. After the first match, a value will be stashed somewhere and used elsewhere in the firmware when making certain decisions. An example of this may be only enabling certain devices (such as the HPET) if the OS claims to support Windows Vista.

As I mentioned, recent versions of Linux no longer claim to support the Linux interface. There's a couple of reasons for this. Firstly, some platforms break if they're told that they're running on Linux. It's usually an entirely untested codepath. Secondly, the whole point of the _OSI method is to provide the platform with information about the interface supported by an OS. "Linux" is too coarse grained - we make no guarantees that the interface between the OS and the platform will remain constant. "Linux 2.6.25" isn't all that much better, since distribution patches may alter the behaviour and BIOSes would become specific to a given kernel version. We could have something like "Linux ABI 1" and then bump that every time we altered the behaviour of the kernel in this respect, but this would become unwieldy fairly quickly (what would count as an ABI breaking change?)

So what kind of interface can we claim to provide? The sad truth of the matter is that most vendors will only test their code against Windows, and that as a result Windows provides the de-facto specification for OS/platform interaction. We could skip claiming to be Windows, but (in the best case) that means that the system will assume it's working with an OS that supports no advanced features. Rather than getting support for brightness changes being handled by the OS, we get stuck with SMM traps and unexpectedly missing time. If we want hardware to work to its full potential, we need to claim to be a recent version of Windows.

Does this mean the entire _OSI mechanism is useless? Not really. It's still useful for providing information about supported functionality. One example used in the spec is whether or not the OS implements the ACPI 3.0 thermal model. Another obvious (but unspecced) example might be whether or not the video opregion spec is implemented in the OS. _OSI strings which explicitly advertise the existence of advanced functionality are something that should be specified and encouraged. What they shouldn't be used for is as a way of advertising lacking functionality, which is effectively the only way that Linux can be usefully interpreted today. We don't want machines to automatically repost their video if they detect they're running Linux. It makes it harder to implement proper kernel-level graphics resume code. We don't want them to suddenly alter their keyboard behaviour, because that probably makes it harder to support older machines that don't have these workarounds.

Message to vendors: If we're not behaving in the same way as Windows does, let us know. We'll fix it. This has the benefit of fixing not only your latest and greatest platform, but also all the older ones that expected the same behaviour. Please don't try to work around our bugs in your BIOS - it just means that we need to special case you forever, and in the long run your hardware won't work as well as it would if we just fixed things properly.
Tags: advogato

Comments for this post were locked by the author