요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
==========================
ACPI _OSI and _REV methods
==========================
An ACPI BIOS can use the "Operating System Interfaces" method (_OSI)
to find out what the operating system supports. Eg. If BIOS
AML code includes _OSI("XYZ"), the kernel's AML interpreter
can evaluate that method, look to see if it supports 'XYZ'
and answer YES or NO to the BIOS.
The ACPI _REV method returns the "Revision of the ACPI specification
that OSPM supports"
This document explains how and why the BIOS and Linux should use these methods.
It also explains how and why they are widely misused.
How to use _OSI
===============
Linux runs on two groups of machines -- those that are tested by the OEM
to be compatible with Linux, and those that were never tested with Linux,
but where Linux was installed to replace the original OS (Windows or OSX).
The larger group is the systems tested to run only Windows. Not only that,
but many were tested to run with just one specific version of Windows.
So even though the BIOS may use _OSI to query what version of Windows is running,
only a single path through the BIOS has actually been tested.
Experience shows that taking untested paths through the BIOS
exposes Linux to an entire category of BIOS bugs.
For this reason, Linux _OSI defaults must continue to claim compatibility
with all versions of Windows.
But Linux isn't actually compatible with Windows, and the Linux community
has also been hurt with regressions when Linux adds the latest version of
Windows to its list of _OSI strings. So it is possible that additional strings
will be more thoroughly vetted before shipping upstream in the future.
But it is likely that they will all eventually be added.
What should an OEM do if they want to support Linux and Windows
using the same BIOS image? Often they need to do something different
for Linux to deal with how Linux is different from Windows.
In this case, the OEM should create custom ASL to be executed by the
Linux kernel and changes to Linux kernel drivers to execute this custom
ASL. The easiest way to accomplish this is to introduce a device specific
method (_DSM) that is called from the Linux kernel.
In the past the kernel used to support something like:
_OSI("Linux-OEM-my_interface_name")
where 'OEM' is needed if this is an OEM-specific hook,
and 'my_interface_name' describes the hook, which could be a
quirk, a bug, or a bug-fix.
However this was discovered to be abused by other BIOS vendors to change
completely unrelated code on completely unrelated systems. This prompted
an evaluation of all of its uses. This uncovered that they aren't needed
for any of the original reasons. As such, the kernel will not respond to
any custom Linux-* strings by default.
That was easy. Read on, to find out how to do it wrong.
Before _OSI, there was _OS
==========================
ACPI 1.0 specified "_OS" as an
"object that evaluates to a string that identifies the operating system."
The ACPI BIOS flow would include an evaluation of _OS, and the AML
interpreter in the kernel would return to it a string identifying the OS:
Windows 98, SE: "Microsoft Windows"
Windows ME: "Microsoft WindowsME:Millennium Edition"
Windows NT: "Microsoft Windows NT"
The idea was on a platform tasked with running multiple OS's,
the BIOS could use _OS to enable devices that an OS
might support, or enable quirks or bug workarounds
necessary to make the platform compatible with that pre-existing OS.
But _OS had fundamental problems. First, the BIOS needed to know the name
of every possible version of the OS that would run on it, and needed to know
all the quirks of those OS's. Certainly it would make more sense
for the BIOS to ask *specific* things of the OS, such
"do you support a specific interface", and thus in ACPI 3.0,
_OSI was born to replace _OS.
_OS was abandoned, though even today, many BIOS look for
_OS "Microsoft Windows NT", though it seems somewhat far-fetched
that anybody would install those old operating systems
over what came with the machine.
Linux answers "Microsoft Windows NT" to please that BIOS idiom.
That is the *only* viable strategy, as that is what modern Windows does,
and so doing otherwise could steer the BIOS down an untested path.
_OSI is born, and immediately misused
=====================================
With _OSI, the *BIOS* provides the string describing an interface,
and asks the OS: "YES/NO, are you compatible with this interface?"
eg. _OSI("3.0 Thermal Model") would return TRUE if the OS knows how
to deal with the thermal extensions made to the ACPI 3.0 specification.
An old OS that doesn't know about those extensions would answer FALSE,
and a new OS may be able to return TRUE.
For an OS-specific interface, the ACPI spec said that the BIOS and the OS
were to agree on a string of the form such as "Windows-interface_name".
But two bad things happened. First, the Windows ecosystem used _OSI
not as designed, but as a direct replacement for _OS -- identifying
the OS version, rather than an OS supported interface. Indeed, right
from the start, the ACPI 3.0 spec itself codified this misuse
in example code using _OSI("Windows 2001").
This misuse was adopted and continues today.
Linux had no choice but to also return TRUE to _OSI("Windows 2001")
and its successors. To do otherwise would virtually guarantee breaking
a BIOS that has been tested only with that _OSI returning TRUE.
This strategy is problematic, as Linux is never completely compatible with
the latest version of Windows, and sometimes it takes more than a year
to iron out incompatibilities.
Not to be out-done, the Linux community made things worse by returning TRUE
to _OSI("Linux"). Doing so is even worse than the Windows misuse
of _OSI, as "Linux" does not even contain any version information.
_OSI("Linux") led to some BIOS' malfunctioning due to BIOS writer's
using it in untested BIOS flows. But some OEM's used _OSI("Linux")
in tested flows to support real Linux features. In 2009, Linux
removed _OSI("Linux"), and added a cmdline parameter to restore it
for legacy systems still needed it. Further a BIOS_BUG warning prints
for all BIOS's that invoke it.
No BIOS should use _OSI("Linux").
The result is a strategy for Linux to maximize compatibility with
ACPI BIOS that are tested on Windows machines. There is a real risk
of over-stating that compatibility; but the alternative has often been
catastrophic failure resulting from the BIOS taking paths that
were never validated under *any* OS.
Do not use _REV
===============
Since _OSI("Linux") went away, some BIOS writers used _REV
to support Linux and Windows differences in the same BIOS.
_REV was defined in ACPI 1.0 to return the version of ACPI
supported by the OS and the OS AML interpreter.
Modern Windows returns _REV = 2. Linux used ACPI_CA_SUPPORT_LEVEL,
which would increment, based on the version of the spec supported.
Unfortunately, _REV was also misused. eg. some BIOS would check
for _REV = 3, and do something for Linux, but when Linux returned
_REV = 4, that support broke.
In response to this problem, Linux returns _REV = 2 always,
from mid-2015 onward. The ACPI specification will also be updated
to reflect that _REV is deprecated, and always returns 2.
Apple Mac and _OSI("Darwin")
============================
On Apple's Mac platforms, the ACPI BIOS invokes _OSI("Darwin")
to determine if the machine is running Apple OSX.
Like Linux's _OSI("*Windows*") strategy, Linux defaults to
answering YES to _OSI("Darwin") to enable full access
to the hardware and validated BIOS paths seen by OSX.
Just like on Windows-tested platforms, this strategy has risks.
Starting in Linux-3.18, the kernel answered YES to _OSI("Darwin")
for the purpose of enabling Mac Thunderbolt support. Further,
if the kernel noticed _OSI("Darwin") being invoked, it additionally
disabled all _OSI("*Windows*") to keep poorly written Mac BIOS
from going down untested combinations of paths.
The Linux-3.18 change in default caused power regressions on Mac
laptops, and the 3.18 implementation did not allow changing
the default via cmdline "acpi_osi=!Darwin". Linux-4.7 fixed
the ability to use acpi_osi=!Darwin as a workaround, and
we hope to see Mac Thunderbolt power management support in Linux-4.11.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
_OSI와 _REV의 역할
1-18ACPI BIOS는 `_OSI`(Operating System Interfaces) 메서드로 운영체제가 특정 인터페이스를 지원하는지 묻는다. 예를 들어 AML에 `_OSI("XYZ")`가 있으면 커널의 AML 인터프리터가 `XYZ` 지원 여부를 평가해 BIOS에 YES 또는 NO로 응답한다. 이 질의의 본래 대상은 운영체제 이름이 아니라 운영체제가 이해하는 인터페이스다.
`_REV`는 OSPM이 지원하는 ACPI 명세의 revision을 반환하도록 정의된 메서드다. 여기서 OSPM은 운영체제 주도 전원 관리 계층을 뜻한다. 그러나 실제 firmware에서는 `_OSI`와 `_REV`가 운영체제 판별 수단처럼 널리 오용되었고, 그 결과 Linux는 명세의 이상적인 의미뿐 아니라 이미 검증된 BIOS 실행 경로도 고려해야 한다.
이 문서는 두 메서드의 명세상 목적, Linux가 취하는 호환성 응답, OEM이 Linux 전용 동작을 구현해야 할 때의 권장 방식, 과거의 오용이 현재 기본값에 남긴 제약을 설명한다. YES 응답은 Linux가 해당 Windows 또는 macOS와 완전히 같다는 선언이 아니라 BIOS가 시험하지 않은 분기로 들어가는 것을 피하려는 호환성 정책일 수 있다.
_OSI와 _REV가 무엇을 묻고 무엇을 반환하는지 구분한다.
AML 질의가 커널을 거쳐 BIOS 분기 선택으로 이어지는 순서다.
.. SPDX-License-Identifier: GPL-2.0
==========================
ACPI _OSI and _REV methods
==========================
An ACPI BIOS can use the "Operating System Interfaces" method (_OSI)
to find out what the operating system supports. Eg. If BIOS
AML code includes _OSI("XYZ"), the kernel's AML interpreter
can evaluate that method, look to see if it supports 'XYZ'
and answer YES or NO to the BIOS.
The ACPI _REV method returns the "Revision of the ACPI specification
that OSPM supports"
This document explains how and why the BIOS and Linux should use these methods.
It also explains how and why they are widely misused.
OEM이 _OSI를 사용해야 하는 방식
19-62Linux가 실행되는 장비는 OEM이 Linux 호환성을 직접 시험한 장비와, Windows 또는 OSX용으로만 시험된 뒤 원래 운영체제를 Linux로 교체한 장비로 나뉜다. 후자가 더 큰 집단이며, 많은 시스템은 특정 Windows 버전 하나에서 BIOS 경로 하나만 실제 검증했다. Linux가 다른 `_OSI` 응답으로 시험되지 않은 경로를 선택하면 새로운 종류의 BIOS 결함에 노출될 수 있다.
이 때문에 Linux의 기본 `_OSI` 정책은 여러 Windows 버전과의 호환성을 계속 주장한다. 하지만 Linux가 실제로 Windows와 완전히 호환되는 것은 아니다. 최신 Windows 문자열을 목록에 추가했을 때 Linux 회귀가 발생한 경험도 있으므로, 새 문자열은 upstream 배포 전에 더 엄격하게 검증될 수 있다. 장기적으로는 해당 문자열도 결국 추가될 가능성이 높다는 것이 원문의 판단이다.
하나의 BIOS image로 Linux와 Windows를 함께 지원하면서 Linux에만 다른 동작이 필요하다면, OEM은 Linux 커널이 실행할 custom ASL과 그 ASL을 호출할 Linux driver 변경을 함께 제공해야 한다. 가장 단순한 권장 방식은 Linux 커널에서 호출하는 device-specific method인 `_DSM`을 도입하는 것이다. 이는 범용 운영체제 판별 문자열보다 기능의 소유권과 호출 지점을 명확히 한다.
과거에는 `_OSI("Linux-OEM-my_interface_name")` 같은 문자열을 지원했다. `OEM`은 OEM 전용 hook임을 나타내고 `my_interface_name`은 quirk, bug 또는 bug-fix 성격의 hook을 설명했다. 그러나 다른 BIOS 업체가 전혀 관계없는 시스템과 코드 경로를 바꾸는 데 이 문자열을 악용했다. 전체 사용 사례를 재평가한 결과 원래 목적에도 필요하지 않았으므로, 커널은 기본적으로 어떤 custom `Linux-*` 문자열에도 응답하지 않는다.
검증 이력이 _OSI 기본 정책에 미치는 영향을 비교한다.
운영체제 이름을 추측하는 문자열 대신 명시적인 기능 계약을 만든다.
How to use _OSI
===============
Linux runs on two groups of machines -- those that are tested by the OEM
to be compatible with Linux, and those that were never tested with Linux,
but where Linux was installed to replace the original OS (Windows or OSX).
The larger group is the systems tested to run only Windows. Not only that,
but many were tested to run with just one specific version of Windows.
So even though the BIOS may use _OSI to query what version of Windows is running,
only a single path through the BIOS has actually been tested.
Experience shows that taking untested paths through the BIOS
exposes Linux to an entire category of BIOS bugs.
For this reason, Linux _OSI defaults must continue to claim compatibility
with all versions of Windows.
But Linux isn't actually compatible with Windows, and the Linux community
has also been hurt with regressions when Linux adds the latest version of
Windows to its list of _OSI strings. So it is possible that additional strings
will be more thoroughly vetted before shipping upstream in the future.
But it is likely that they will all eventually be added.
What should an OEM do if they want to support Linux and Windows
using the same BIOS image? Often they need to do something different
for Linux to deal with how Linux is different from Windows.
In this case, the OEM should create custom ASL to be executed by the
Linux kernel and changes to Linux kernel drivers to execute this custom
ASL. The easiest way to accomplish this is to introduce a device specific
method (_DSM) that is called from the Linux kernel.
In the past the kernel used to support something like:
_OSI("Linux-OEM-my_interface_name")
where 'OEM' is needed if this is an OEM-specific hook,
and 'my_interface_name' describes the hook, which could be a
quirk, a bug, or a bug-fix.
However this was discovered to be abused by other BIOS vendors to change
completely unrelated code on completely unrelated systems. This prompted
an evaluation of all of its uses. This uncovered that they aren't needed
for any of the original reasons. As such, the kernel will not respond to
any custom Linux-* strings by default.
That was easy. Read on, to find out how to do it wrong.
_OSI 이전의 _OS와 구조적 한계
63-97ACPI 1.0은 `_OS`를 운영체제를 식별하는 문자열로 평가되는 object로 정의했다. BIOS가 `_OS`를 평가하면 커널의 AML 인터프리터가 운영체제 식별 문자열을 반환했다. 원문에 기록된 값은 Windows 98/SE의 `"Microsoft Windows"`, Windows ME의 `"Microsoft WindowsME:Millennium Edition"`, Windows NT의 `"Microsoft Windows NT"`다.
여러 운영체제를 실행하는 플랫폼에서는 BIOS가 `_OS` 결과에 따라 특정 장치를 활성화하거나, 기존 운영체제와의 호환성에 필요한 quirk와 bug workaround를 선택한다는 구상이었다. 그러나 이 방식은 BIOS가 앞으로 실행될 모든 운영체제 버전의 이름과 각 버전의 모든 예외를 미리 알아야 한다는 근본적 한계를 가졌다.
운영체제 이름 전체를 맞히게 하는 것보다 특정 인터페이스 지원 여부를 질문하는 편이 합리적이므로 ACPI 3.0에서 `_OSI`가 `_OS`를 대체했다. 그럼에도 많은 BIOS는 지금도 `_OS`가 `"Microsoft Windows NT"`인지 확인한다. 현대 Windows도 그 문자열을 반환하므로 Linux 역시 같은 BIOS 관용구를 만족시키기 위해 `"Microsoft Windows NT"`라고 답한다.
이 응답은 오래된 Windows NT를 가장하는 것이 목적이 아니다. 다른 값을 반환해 BIOS를 한 번도 검증하지 않은 분기로 보내는 것을 막기 위한 사실상 유일한 전략이다. 따라서 문자열의 표면적 이름과 Linux가 그 값을 유지하는 호환성 이유를 분리해서 이해해야 한다.
ACPI 1.0 시대에 AML 인터프리터가 반환하던 값을 그대로 보존한다.
운영체제 이름 판별의 한계를 인터페이스 질의로 바꾼 설계 변화다.
Before _OSI, there was _OS
==========================
ACPI 1.0 specified "_OS" as an
"object that evaluates to a string that identifies the operating system."
The ACPI BIOS flow would include an evaluation of _OS, and the AML
interpreter in the kernel would return to it a string identifying the OS:
Windows 98, SE: "Microsoft Windows"
Windows ME: "Microsoft WindowsME:Millennium Edition"
Windows NT: "Microsoft Windows NT"
The idea was on a platform tasked with running multiple OS's,
the BIOS could use _OS to enable devices that an OS
might support, or enable quirks or bug workarounds
necessary to make the platform compatible with that pre-existing OS.
But _OS had fundamental problems. First, the BIOS needed to know the name
of every possible version of the OS that would run on it, and needed to know
all the quirks of those OS's. Certainly it would make more sense
for the BIOS to ask *specific* things of the OS, such
"do you support a specific interface", and thus in ACPI 3.0,
_OSI was born to replace _OS.
_OS was abandoned, though even today, many BIOS look for
_OS "Microsoft Windows NT", though it seems somewhat far-fetched
that anybody would install those old operating systems
over what came with the machine.
Linux answers "Microsoft Windows NT" to please that BIOS idiom.
That is the *only* viable strategy, as that is what modern Windows does,
and so doing otherwise could steer the BIOS down an untested path.
_OSI의 탄생과 운영체제 판별 오용
98-145`_OSI`의 설계에서는 BIOS가 인터페이스를 설명하는 문자열을 제시하고 운영체제에 그 인터페이스와 호환되는지 YES/NO로 묻는다. 예를 들어 `_OSI("3.0 Thermal Model")`은 운영체제가 ACPI 3.0 thermal extension을 처리할 수 있으면 TRUE, 모르면 FALSE를 반환해야 한다. 운영체제 전용 인터페이스도 BIOS와 운영체제가 `"Windows-interface_name"` 같은 문자열에 합의하는 형태였다.
하지만 Windows 생태계는 `_OSI`를 지원 인터페이스가 아니라 운영체제 버전을 식별하는 `_OS`의 직접 대체물로 사용했다. ACPI 3.0 명세의 예제 코드부터 `_OSI("Windows 2001")`을 사용해 이 오용을 굳혔고, 그 관행은 계속되었다. 특정 응답이 TRUE인 경로만 시험한 BIOS를 깨뜨리지 않기 위해 Linux도 `_OSI("Windows 2001")`과 후속 문자열에 TRUE를 반환해야 했다.
이 전략에도 비용이 있다. Linux는 최신 Windows와 완전히 호환되지 않으며 차이를 정리하는 데 1년 이상 걸릴 때도 있다. 반대로 해당 문자열을 거부하면 BIOS가 전혀 검증되지 않은 경로를 선택해 치명적으로 실패할 가능성이 있다. Linux의 응답은 과도한 호환성 주장 위험과 미검증 firmware 경로 위험 사이의 현실적인 선택이다.
Linux 공동체도 과거 `_OSI("Linux")`에 TRUE를 반환해 문제를 키웠다. 버전 정보조차 없는 문자열이 BIOS 작성자에게 시험되지 않은 Linux 전용 분기를 만들도록 했고 일부 BIOS가 오동작했다. 실제 Linux 기능을 위해 검증된 흐름을 만든 OEM도 있었지만, Linux는 2009년에 기본 응답을 제거하고 legacy system용 command line 복원 매개변수를 추가했다. 이를 호출하는 모든 BIOS에는 `BIOS_BUG` 경고가 출력된다.
결론은 단호하다. BIOS는 `_OSI("Linux")`를 사용해서는 안 된다. Linux는 Windows에서 검증된 ACPI BIOS 경로와의 호환성을 최대화하되, 운영체제 이름 문자열을 새로운 firmware 기능 계약으로 사용하지 않는다.
문자열이 표현해야 하는 대상과 실제 관행을 대비한다.
기능 지원 의도와 BIOS 오동작을 거쳐 현재 정책에 이른 과정이다.
_OSI is born, and immediately misused
=====================================
With _OSI, the *BIOS* provides the string describing an interface,
and asks the OS: "YES/NO, are you compatible with this interface?"
eg. _OSI("3.0 Thermal Model") would return TRUE if the OS knows how
to deal with the thermal extensions made to the ACPI 3.0 specification.
An old OS that doesn't know about those extensions would answer FALSE,
and a new OS may be able to return TRUE.
For an OS-specific interface, the ACPI spec said that the BIOS and the OS
were to agree on a string of the form such as "Windows-interface_name".
But two bad things happened. First, the Windows ecosystem used _OSI
not as designed, but as a direct replacement for _OS -- identifying
the OS version, rather than an OS supported interface. Indeed, right
from the start, the ACPI 3.0 spec itself codified this misuse
in example code using _OSI("Windows 2001").
This misuse was adopted and continues today.
Linux had no choice but to also return TRUE to _OSI("Windows 2001")
and its successors. To do otherwise would virtually guarantee breaking
a BIOS that has been tested only with that _OSI returning TRUE.
This strategy is problematic, as Linux is never completely compatible with
the latest version of Windows, and sometimes it takes more than a year
to iron out incompatibilities.
Not to be out-done, the Linux community made things worse by returning TRUE
to _OSI("Linux"). Doing so is even worse than the Windows misuse
of _OSI, as "Linux" does not even contain any version information.
_OSI("Linux") led to some BIOS' malfunctioning due to BIOS writer's
using it in untested BIOS flows. But some OEM's used _OSI("Linux")
in tested flows to support real Linux features. In 2009, Linux
removed _OSI("Linux"), and added a cmdline parameter to restore it
for legacy systems still needed it. Further a BIOS_BUG warning prints
for all BIOS's that invoke it.
No BIOS should use _OSI("Linux").
The result is a strategy for Linux to maximize compatibility with
ACPI BIOS that are tested on Windows machines. There is a real risk
of over-stating that compatibility; but the alternative has often been
catastrophic failure resulting from the BIOS taking paths that
were never validated under *any* OS.
_REV를 사용하지 않아야 하는 이유
146-165`_OSI("Linux")`가 사라진 뒤 일부 BIOS 작성자는 같은 BIOS에서 Linux와 Windows의 동작을 구분하려고 `_REV`를 사용했다. `_REV`는 ACPI 1.0에서 운영체제와 OS AML 인터프리터가 지원하는 ACPI 버전을 반환하도록 정의되었지만, 운영체제 식별자는 아니다.
현대 Windows는 `_REV = 2`를 반환한다. Linux는 한때 지원 명세 버전에 따라 증가하는 `ACPI_CA_SUPPORT_LEVEL`을 사용했다. 이 차이를 Linux 판별에 사용한 BIOS는 `_REV = 3`일 때 특정 Linux 동작을 선택했지만 Linux가 `_REV = 4`를 반환하자 그 지원이 깨지는 식의 오류를 만들었다.
이 문제에 대응해 Linux는 2015년 중반부터 `_REV = 2`를 항상 반환한다. ACPI 명세도 `_REV`를 deprecated로 표시하고 항상 2를 반환하도록 반영될 예정이다. 따라서 firmware는 `_REV` 값으로 Linux를 탐지하거나 기능 분기를 만들어서는 안 된다.
값의 변화가 운영체제 판별에 부적합한 이유를 보여 준다.
revision 보고와 운영체제 판별을 분리한다.
Do not use _REV
===============
Since _OSI("Linux") went away, some BIOS writers used _REV
to support Linux and Windows differences in the same BIOS.
_REV was defined in ACPI 1.0 to return the version of ACPI
supported by the OS and the OS AML interpreter.
Modern Windows returns _REV = 2. Linux used ACPI_CA_SUPPORT_LEVEL,
which would increment, based on the version of the spec supported.
Unfortunately, _REV was also misused. eg. some BIOS would check
for _REV = 3, and do something for Linux, but when Linux returned
_REV = 4, that support broke.
In response to this problem, Linux returns _REV = 2 always,
from mid-2015 onward. The ACPI specification will also be updated
to reflect that _REV is deprecated, and always returns 2.
Apple Mac과 _OSI("Darwin")
166-187Apple Mac의 ACPI BIOS는 기계가 Apple OSX를 실행하는지 확인하려고 `_OSI("Darwin")`을 호출한다. Linux는 `_OSI("*Windows*")`에 대한 정책과 마찬가지로, OSX에서 확인된 BIOS 경로와 하드웨어 전체 접근을 활성화하기 위해 기본적으로 `_OSI("Darwin")`에 YES라고 답한다. 이 선택도 실제 운영체제가 같다는 뜻은 아니며 Windows 시험 장비에서와 같은 위험을 가진다.
Linux-3.18부터 커널은 Mac Thunderbolt 지원을 활성화하려고 `_OSI("Darwin")`에 YES를 반환했다. 또한 이 호출을 감지하면 잘못 작성된 Mac BIOS가 Windows 경로와 Darwin 경로의 시험되지 않은 조합으로 들어가지 않도록 모든 `_OSI("*Windows*")` 응답을 비활성화했다.
Linux-3.18의 기본값 변경은 Mac laptop에서 전력 회귀를 일으켰고 당시 구현은 command line의 `acpi_osi=!Darwin`으로 기본값을 바꾸는 것도 허용하지 않았다. Linux-4.7은 이 workaround를 사용할 수 있게 수정했다. 문서 작성 시점에는 Linux-4.11에서 Mac Thunderbolt power management 지원을 기대한다고 기록되어 있다.
따라서 Darwin 처리는 단일 YES 응답만의 문제가 아니다. Darwin 호출 감지, Windows 계열 응답 비활성화, command line override 가능 여부, Thunderbolt 전원 관리 상태가 kernel version에 따라 함께 달라진다.
원문에 명시된 kernel version과 동작을 시간순으로 정리한다.
BIOS 호출 감지부터 경로 제한과 workaround까지의 관계다.
Apple Mac and _OSI("Darwin")
============================
On Apple's Mac platforms, the ACPI BIOS invokes _OSI("Darwin")
to determine if the machine is running Apple OSX.
Like Linux's _OSI("*Windows*") strategy, Linux defaults to
answering YES to _OSI("Darwin") to enable full access
to the hardware and validated BIOS paths seen by OSX.
Just like on Windows-tested platforms, this strategy has risks.
Starting in Linux-3.18, the kernel answered YES to _OSI("Darwin")
for the purpose of enabling Mac Thunderbolt support. Further,
if the kernel noticed _OSI("Darwin") being invoked, it additionally
disabled all _OSI("*Windows*") to keep poorly written Mac BIOS
from going down untested combinations of paths.
The Linux-3.18 change in default caused power regressions on Mac
laptops, and the 3.18 implementation did not allow changing
the default via cmdline "acpi_osi=!Darwin". Linux-4.7 fixed
the ability to use acpi_osi=!Darwin as a workaround, and
we hope to see Mac Thunderbolt power management support in Linux-4.11.
요약·해설
osi.rst:1-187`_OSI`는 원래 운영체제가 특정 인터페이스를 지원하는지 BIOS가 YES/NO로 묻는 메서드다. 그러나 실제 생태계에서는 Windows 버전 판별 수단으로 오용되었고, Linux는 Windows에서 시험된 BIOS 경로를 유지하기 위해 여러 Windows 문자열에 호환 응답을 한다. 이는 완전한 Windows 호환 선언이 아니다.
OEM이 Linux 전용 동작을 추가해야 한다면 custom `Linux-*` 문자열이나 `_OSI("Linux")`, `_REV` 값으로 운영체제를 판별하지 말아야 한다. Linux driver가 명시적으로 호출하는 `_DSM`과 custom ASL을 함께 설계하는 것이 권장된다. `_REV`는 2015년 중반 이후 Linux에서도 항상 2를 반환한다.
Mac에서는 Linux-3.18부터 `_OSI("Darwin")`에 YES라고 답하고 Windows 계열 `_OSI` 응답을 끈다. 전력 회귀를 위한 `acpi_osi=!Darwin` workaround는 Linux-4.7에서 정상화되었다. 이 정책들은 검증된 firmware 경로를 지키기 위한 역사적 호환성 조치다.
문서의 권장 사항과 금지 사항을 구현 선택 기준으로 묶는다.
문자열 응답을 운영체제 동일성 선언으로 오해하지 않기 위한 순서다.