5

This is a question about a problem I could fix but I do not know why the fix works.

I wanted to be able to adjust the backlight from keyboard and the only thing which fixed that was changing a line in the grub as

GRUB_CMDLINE_LINUX_DEFAULT="acpi_osi="

does anyone know why this fixes the backlight issue?

I am using Debian 8.

4

2 Answers 2

9

During operating system boot, the OS obtains various ACPI tables from the BIOS and interprets the "tables", which really look more like program code. One quite popular table is the DSDT, but it's not alone.

The ACPI tables are created in the form of textual source code (see the example linked above), and are compiled into binary form using a tool called iasl (by Intel). The tables are stored in the BIOS and processed by the OS in the binary form (like an intermediate byte-code or some such), but can be "disassembled" back into source code, if needed. Which is sometimes used by Linux tinkerers to correct bugs or ACPI "version mismatches": the original table is disassembled, possibly corrected in the source code, recompiled by a current version of the IASL, and provided to the Linux kernel as a custom replacement...

The ACPI tables (including the DSDT) contain conditional branches - and the ACPI table being interpretted by the booting OS can test for the OS version using a method called _OSI. The host OS, interpretting the table, provides an "OS version string" to the _OSI method. Such as, for some reason, an _OSI string "Windows 2009" refers to "Windows 7" in our reality. Note that this is allegedly not the purpose originally intended for the _OSI method, but never mind :-)

In other words, the "program" embodied in an ACPI table (while being interpretted by a host OS) can test, under what Windows version it is running, and modify its behavior based on that. It can init the hardware and various BIOS service interfaces/structures, based on the Windows version detected. Linux has its own assigned _OSI ident, and so does MacOS for instance... yet, as the BIOSes in x86 motherboards typically get tested against contemporary Windows versions, you may actually have better luck if you try to make the ACPI table believe that it's being interpretted by some particular Windows version, rather than by Linux. (Or to try to avoid hitting the "default case" in the branching ACPI code, which may not be well defined.) Which is what the kernel cmdline argument of acpi_osi="some string" is good for. The details of this and other related arguments are somewhat documented in the Linux "kernel parameters" guide.

Apart from display backlight, the acpi_osi string can influence miscellaneous other aspects of the BIOS and OS behavior during boot. As an example, just at this moment I'm playing with an old Acer Extensa 5220 laptop (C2D, i965GM north bridge) and in default config, it often fails to resume from suspend (ACPI S3, suspend to RAM). On resume, it would freeze with a black screen and backlight on, or it would perform two restarts and then boot from scratch. I updated the BIOS which alone did not help, but it gave me a certainty that this BIOS update (1.35) was intended to work well with Windows 7. So after trying a number of other things, I finally have pretty good results with

acpi_osi=! acpi_osi="Windows 2009"

The first part, acpi_osi=! , means "forget any acpi_osi strings that you know at this point" (it's actually a list of strings, rather than just one string, apparently - duh). So we first clear whatever the interpretter originally used, and then set the one desired string. To make it work with a modern Linux kernel, it might be a good idea to specify the most modern Windows version that the BIOS nominally supports.

Note that you need quotation marks around "Windows 2009", because the string contains a blank character (ASCII 'space'). Which turns out to be a problem if this cmdline arg needs to be entered into a shell variable in some distro-specific config file, such as /etc/default/grub in Debian and friends (Ubuntu). In that case, just use acpi_osi=\"Windows 2009\" , i.e. use a backslash to "escape" each quotation mark that should make it to the kernel command line. If you then run update-grub (again Debian/Ubuntu), the backslashes get stripped, and the quotation marks end up verbatim in /boot/grub/grub.cfg. Interestingly, if you later check with cat /proc/cmdline , you'll probably find out that the first quotation mark has moved to the very start of the argument: "acpi_osi=Windows 2009" which looks slightly bizzarre :-)

I've found out that I should NOT mess with acpi_os_name or acpi_sleep (which otherwise also look promising). YMMV.

Note that this is yet another incarnation of a general backward compatibility problem. Cross-compatibility between two different pieces of software, created very far apart in time. Speaking of suspend and resume, Linux has lost support for the old and simple APM BIOS call known as "set power state", so the only interface you can use for suspend+resume is ACPI, which itself is pretty complex, has evolved through several major versions, and very modern Linux versions are no longer thoroughly tested on very old hardware (and its BIOS), and the BIOS probably wasn't free of bugs even when it was new... and even ACPI is now getting superseded by UEFI, which builds on ACPI and brings further peculiarities of its own...

3
  • What happened if you changed acpi_os_name or acpi_sleep?
    – Tom Hale
    Sep 18, 2020 at 8:07
  • @Tom Hale : it's been a while, I don't remember anymore - either the suspend/resume did not work correctly or the machine didn't even boot. But even this is probably very specific to a particular machine model and BIOS version...
    – frr
    Sep 19, 2020 at 16:42
  • forum.manjaro.org/t/… suggests that you use single quotes instead: GRUB_CMDLINE_LINUX="acpi_osi='Windows 2012'"
    – JPT
    Mar 2, 2022 at 9:24
3

acpi_osi= causes Linux to disable the ACPI Operating System Identification function (_OSI) when executing ACPI code provided by the mainboard.

Your laptop probably checks for specific Windows versions to switch between different modes of how the brightness hotkeys are reported to the OS. Linux usually presents itself as a recent Windows version to ACPI code, so acpi_osi= lets all these checks fail and apparently causes to ACPI code to report the brightness hotkeys in a way that your Linux installation understands.

See https://unix.stackexchange.com/a/268106/147970 for more details on the effects of acpi_osi=….

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .