以有效率的方式運用硬體資源是很重要的,電源與資源管理讓作業系統可以監控系統的限制,並且在系統溫度意外升高時能夠發出警報。早期提供電源管理的規範是進階電源管理 (Advanced Power Management, APM),APM 可根據系統的使用狀況來來控制電源用量。然而,使用 APM 要作業系統來管理系統的電源用量和溫度屬性是困難且沒有彈性的,因為硬體是由 BIOS 所管理,使用者對電源管理設定只有有限的設定性與可見性,且 APM BIOS 是由供應商提供且特定於某些硬體平台,而作業系統中必透過 APM 驅動程式做為中介存取 APM 軟體介面才能夠管理電源等級。
在 APM 有四個主要的問題。第一,電源管理是由供應商特定的 BIOS 來完成,與作業系統是分開的。例如,使用者可在 APM BIOS 設定硬碟的閒置時間值,在超過時間時 BIOS 可在未徵得作業系統的同意下降低硬碟的轉速。第二,APM 的邏輯是內嵌在 BIOS 當中的,並且在作業系統範圍之外運作,這代表使用者只能夠透過燒錄新的韌體到 ROM 來修正 APM BIOS 中的問題,而這樣的程序是危險的,若失敗,可能會讓系統進入無法復原的狀態。第三,APM 是供應商特定的技術,這代表有許多重複的工作,在一個供應商的 BIOS 找到的問題在其他的供應商卻沒有解決。最後一點,APM BIOS 並沒有足夠的空間來實作複雜的電源管理政策或可良好適應主機用途的程式。
Plug and Play BIOS (PNPBIOS) 在很多情況下並不可靠,PNPBIOS 是 16 位元的技術,所以作業系統必須模擬 16 位元才能存取 PNPBIOS。FreeBSD 提供了一個 APM 驅動程式來做 APM,應可用在 2000 年之前所製造的系統,該驅動程式的說明於 apm(4)。
APM 的後繼者是進階設置與電源介面 (Advanced Configuration and Power Interface, ACPI)。ACPI 是一套由供應商聯盟所搛寫出的標準,提供了硬體資源與電源管理的介面,它是 作業系統直接設置與電源管理 (Operating System-directed configuration and Power Management) 關鍵的要素,提供了作業系統更多的控制方式與彈性。
本章節將示範如何在 FreeBSD 設定 ACPI,然後提供一些如何對 ACPI 除錯的提示以及如何提交包含除錯資訊的問題回報,讓開發人員能夠診斷並修正 ACPI 的問題。
在 FreeBSD acpi(4) 驅動程式預設會在系統開始時載入,且不應被編譯到核心當中。這個驅動程式在開機之後無法被卸載,因為系統匯流排會使用它做各種硬體互動。雖然如此,若系統遇到問題,ACPI 還是可以被關閉,在 /boot/loader.conf
中設定 hint.acpi.0.disabled="1"
之後重新開機或在載入程式提示時設定這個變數,如 節 12.2.3, “階段三” 中的說明。
ACPI 與 APM 不能同時存在且應分開使用,若有偵測到有另一個正在執行,要載入的後者將會中斷。
ACPI 可以用來讓系統進入睡眠模式,使用 acpiconf
與 -s
旗標再加上由 1
到 5
的數字。大多數使用者只需使用 1
(快速待命到 RAM) 或 3
(待命到 RAM),選項 5
會執行軟關機 (Soft-off),如同執行 halt -p
一樣。
其他的選項可使用 sysctl
來設定,請參考 acpi(4) 以及 acpiconf(8) 以取得更多資訊。
ACPI is present in all modern computers that conform to the ia32 (x86), ia64 (Itanium), and amd64 (AMD) architectures. The full standard has many features including CPU performance management, power planes control, thermal zones, various battery systems, embedded controllers, and bus enumeration. Most systems implement less than the full standard. For instance, a desktop system usually only implements bus enumeration while a laptop might have cooling and battery management support as well. Laptops also have suspend and resume, with their own associated complexity.
An ACPI-compliant system has various components. The BIOS and chipset vendors provide various fixed tables, such as FADT, in memory that specify things like the APIC map (used for SMP), config registers, and simple configuration values. Additionally, a bytecode table, the Differentiated System Description Table DSDT, specifies a tree-like name space of devices and methods.
The ACPI driver must parse the fixed
tables, implement an interpreter for the bytecode, and modify
device drivers and the kernel to accept information from the
ACPI subsystem. For FreeBSD, Intel® has
provided an interpreter (ACPI-CA) that is
shared with Linux® and NetBSD. The path to the
ACPI-CA source code is
src/sys/contrib/dev/acpica
. The glue
code that allows ACPI-CA to work on FreeBSD is
in src/sys/dev/acpica/Osd
. Finally,
drivers that implement various ACPI devices
are found in src/sys/dev/acpica
.
For ACPI to work correctly, all the parts have to work correctly. Here are some common problems, in order of frequency of appearance, and some possible workarounds or fixes. If a fix does not resolve the issue, refer to 節 11.13.4, “取得與回報除錯資訊” for instructions on how to submit a bug report.
In some cases, resuming from a suspend operation will
cause the mouse to fail. A known work around is to add
hint.psm.0.flags="0x3000"
to
/boot/loader.conf
.
ACPI has three suspend to
RAM (STR) states,
S1
-S3
, and one suspend
to disk state (STD), called
S4
. STD can be
implemented in two separate ways. The
S4
BIOS is a
BIOS-assisted suspend to disk and
S4
OS is implemented
entirely by the operating system. The normal state the
system is in when plugged in but not powered up is
“soft off” (S5
).
Use sysctl hw.acpi
to check for the
suspend-related items. These example results are from a
Thinkpad:
hw.acpi.supported_sleep_state: S3 S4 S5
hw.acpi.s4bios: 0
Use acpiconf -s
to test
S3
, S4
, and
S5
. An s4bios
of one
(1
) indicates
S4
BIOS support instead
of S4
operating system support.
When testing suspend/resume, start with
S1
, if supported. This state is most
likely to work since it does not require much driver
support. No one has implemented S2
,
which is similar to S1
. Next, try
S3
. This is the deepest
STR state and requires a lot of driver
support to properly reinitialize the hardware.
A common problem with suspend/resume is that many device drivers do not save, restore, or reinitialize their firmware, registers, or device memory properly. As a first attempt at debugging the problem, try:
#
sysctl debug.bootverbose=1
#
sysctl debug.acpi.suspend_bounce=1
#
acpiconf -s 3
This test emulates the suspend/resume cycle of all
device drivers without actually going into
S3
state. In some cases, problems such
as losing firmware state, device watchdog time out, and
retrying forever, can be captured with this method. Note
that the system will not really enter S3
state, which means devices may not lose power, and many
will work fine even if suspend/resume methods are totally
missing, unlike real S3
state.
Harder cases require additional hardware, such as a serial port and cable for debugging through a serial console, a Firewire port and cable for using dcons(4), and kernel debugging skills.
To help isolate the problem, unload as many drivers as
possible. If it works, narrow down which driver is the
problem by loading drivers until it fails again. Typically,
binary drivers like nvidia.ko
, display
drivers, and USB will have the most
problems while Ethernet interfaces usually work fine. If
drivers can be properly loaded and unloaded, automate this
by putting the appropriate commands in
/etc/rc.suspend
and
/etc/rc.resume
. Try setting
hw.acpi.reset_video
to 1
if the display is messed up after resume. Try setting
longer or shorter values for
hw.acpi.sleep_delay
to see if that
helps.
Try loading a recent Linux® distribution to see if suspend/resume works on the same hardware. If it works on Linux®, it is likely a FreeBSD driver problem. Narrowing down which driver causes the problem will assist developers in fixing the problem. Since the ACPI maintainers rarely maintain other drivers, such as sound or ATA, any driver problems should also be posted to the freebsd-current list and mailed to the driver maintainer. Advanced users can include debugging printf(3)s in a problematic driver to track down where in its resume function it hangs.
Finally, try disabling ACPI and enabling APM instead. If suspend/resume works with APM, stick with APM, especially on older hardware (pre-2000). It took vendors a while to get ACPI support correct and older hardware is more likely to have BIOS problems with ACPI.
Most system hangs are a result of lost interrupts or an interrupt storm. Chipsets may have problems based on boot, how the BIOS configures interrupts before correctness of the APIC (MADT) table, and routing of the System Control Interrupt (SCI).
Interrupt storms can be distinguished from lost
interrupts by checking the output of
vmstat -i
and looking at the line that
has acpi0
. If the counter is increasing
at more than a couple per second, there is an interrupt
storm. If the system appears hung, try breaking to
DDB (CTRL+ALT+ESC on console) and type
show interrupts
.
When dealing with interrupt problems, try disabling
APIC support with
hint.apic.0.disabled="1"
in
/boot/loader.conf
.
Panics are relatively rare for ACPI
and are the top priority to be fixed. The first step is to
isolate the steps to reproduce the panic, if possible, and
get a backtrace. Follow the advice for enabling
options DDB
and setting up a serial
console in 節 26.6.4, “從序列線路 (Serial Line) 進入 DDB 除錯程式” or setting
up a dump partition. To get a backtrace in
DDB, use tr
. When
handwriting the backtrace, get at least the last five and
the top five lines in the trace.
Then, try to isolate the problem by booting with
ACPI disabled. If that works, isolate
the ACPI subsystem by using various
values of debug.acpi.disable
. See
acpi(4) for some examples.
First, try setting
hw.acpi.disable_on_poweroff="0"
in
/boot/loader.conf
. This keeps
ACPI from disabling various events during
the shutdown process. Some systems need this value set to
1
(the default) for the same reason.
This usually fixes the problem of a system powering up
spontaneously after a suspend or poweroff.
Some BIOS vendors provide incorrect or buggy bytecode. This is usually manifested by kernel console messages like this:
ACPI-1287: *** Error: Method execution failed [\\_SB_.PCI0.LPC0.FIGD._STA] \\
(Node 0xc3f6d160), AE_NOT_FOUND
Often, these problems may be resolved by updating the BIOS to the latest revision. Most console messages are harmless, but if there are other problems, like the battery status is not working, these messages are a good place to start looking for problems.
The BIOS bytecode, known as ACPI Machine Language (AML), is compiled from a source language called ACPI Source Language (ASL). The AML is found in the table known as the Differentiated System Description Table (DSDT).
The goal of FreeBSD is for everyone to have working
ACPI without any user intervention.
Workarounds are still being developed for common mistakes made
by BIOS vendors. The Microsoft®
interpreter (acpi.sys
and
acpiec.sys
) does not strictly check for
adherence to the standard, and thus many
BIOS vendors who only test
ACPI under Windows® never fix their
ASL. FreeBSD developers continue to identify
and document which non-standard behavior is allowed by
Microsoft®'s interpreter and replicate it so that FreeBSD can
work without forcing users to fix the
ASL.
To help identify buggy behavior and possibly fix it
manually, a copy can be made of the system's
ASL. To copy the system's
ASL to a specified file name, use
acpidump
with -t
, to show
the contents of the fixed tables, and -d
, to
disassemble the AML:
#
acpidump -td > my.asl
Some AML versions assume the user is
running Windows®. To override this, set
hw.acpi.osname=
in
"Windows
2009"
/boot/loader.conf
, using the most recent
Windows® version listed in the ASL.
Other workarounds may require my.asl
to be customized. If this file is edited, compile the new
ASL using the following command. Warnings
can usually be ignored, but errors are bugs that will usually
prevent ACPI from working correctly.
#
iasl -f my.asl
Including -f
forces creation of the
AML, even if there are errors during
compilation. Some errors, such as missing return statements,
are automatically worked around by the FreeBSD
interpreter.
The default output filename for iasl
is
DSDT.aml
. Load this file instead of the
BIOS's buggy copy, which is still present
in flash memory, by editing
/boot/loader.conf
as follows:
acpi_dsdt_load="YES"
acpi_dsdt_name="/boot/DSDT.aml"
Be sure to copy DSDT.aml
to
/boot
, then reboot the system. If this
fixes the problem, send a diff(1) of the old and new
ASL to freebsd-acpi so that developers can
work around the buggy behavior in
acpica
.
The ACPI driver has a flexible
debugging facility. A set of subsystems and the level of
verbosity can be specified. The subsystems to debug are
specified as layers and are broken down into components
(ACPI_ALL_COMPONENTS
) and
ACPI hardware support
(ACPI_ALL_DRIVERS
). The verbosity of
debugging output is specified as the level and ranges from
just report errors (ACPI_LV_ERROR
) to
everything (ACPI_LV_VERBOSE
). The level is
a bitmask so multiple options can be set at once, separated by
spaces. In practice, a serial console should be used to log
the output so it is not lost as the console message buffer
flushes. A full list of the individual layers and levels is
found in acpi(4).
Debugging output is not enabled by default. To enable it,
add options ACPI_DEBUG
to the custom kernel
configuration file if ACPI is compiled into
the kernel. Add ACPI_DEBUG=1
to
/etc/make.conf
to enable it globally. If
a module is used instead of a custom kernel, recompile just
the acpi.ko
module as follows:
#
cd /sys/modules/acpi/acpi && make clean && make ACPI_DEBUG=1
Copy the compiled acpi.ko
to
/boot/kernel
and add the desired level
and layer to /boot/loader.conf
. The
entries in this example enable debug messages for all
ACPI components and hardware drivers and
output error messages at the least verbose level:
debug.acpi.layer="ACPI_ALL_COMPONENTS ACPI_ALL_DRIVERS"
debug.acpi.level="ACPI_LV_ERROR"
If the required information is triggered by a specific
event, such as a suspend and then resume, do not modify
/boot/loader.conf
. Instead, use
sysctl
to specify the layer and level after
booting and preparing the system for the specific event. The
variables which can be set using sysctl
are
named the same as the tunables in
/boot/loader.conf
.
Once the debugging information is gathered, it can be sent to freebsd-acpi so that it can be used by the FreeBSD ACPI maintainers to identify the root cause of the problem and to develop a solution.
Before submitting debugging information to this mailing list, ensure the latest BIOS version is installed and, if available, the embedded controller firmware version.
When submitting a problem report, include the following information:
Description of the buggy behavior, including system type, model, and anything that causes the bug to appear. Note as accurately as possible when the bug began occurring if it is new.
The output of dmesg
after running
boot -v
, including any error messages
generated by the bug.
The dmesg
output from boot
-v
with ACPI disabled,
if disabling ACPI helps to fix the
problem.
Output from sysctl hw.acpi
. This
lists which features the system offers.
The URL to a pasted version of the system's ASL. Do not send the ASL directly to the list as it can be very large. Generate a copy of the ASL by running this command:
#
acpidump -dt > name
-system
.asl
Substitute the login name for
name
and manufacturer/model for
system
. For example, use
njl-FooCo6000.asl
.
Most FreeBSD developers watch the FreeBSD-CURRENT mailing list, but one should submit problems to freebsd-acpi to be sure it is seen. Be patient when waiting for a response. If the bug is not immediately apparent, submit a bug report. When entering a PR, include the same information as requested above. This helps developers to track the problem and resolve it. Do not send a PR without emailing freebsd-acpi first as it is likely that the problem has been reported before.
More information about ACPI may be found in the following locations:
The FreeBSD ACPI Mailing List Archives
(https://lists.freebsd.org/pipermail/freebsd-acpi/
)
The ACPI 2.0 Specification (http://acpi.info/spec.htm
)
acpi(4), acpi_thermal(4), acpidump(8), iasl(8), and acpidb(8)
本文及其他文件,可由此下載: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/。
若有 FreeBSD 方面疑問,請先閱讀
FreeBSD 相關文件,如不能解決的話,再洽詢
<questions@FreeBSD.org>。
關於本文件的問題,請洽詢
<doc@FreeBSD.org>。