1ACPI table 在BIOS 里面用ASL code 去描述。而ACPI Table又分成不同类型的Table(RSDT/FADT/DSDT...etc).
2像是我们比较常使用的DSDT Table就是放了一些event code.简单说就是当某个H/W event发生后,系统会依照
描述在这个DSDT Table中的ASL code去执行,而这些Acpi Table 包在BIOS ROM 中的形式是AML Code (类似
机器码)。
3. BIOS在开机过程中会把包在BIOS ROM中的Acpi Table 载入到RAM中,然后留下一些信息给OS来找到他们,
最简单的例子就是RSDP Structure会放在1M以下的某个位置(一般是E0000h~FFFFh),然后OS就可以透过搜寻
Signature(某个标记字)的方式来找到其他的Acpi Table entry point。
4. OS 需要有一个AML翻译器去翻译这些AML code,然后去执行他们。
5.每个 Platform 的host controller的寄存器位置不同,所以BIOS需要透过ACPI Table来告知OS这些寄存器的
位置,这样子做的好处是OS不需要知道你是在什么Platform,因为他只单纯看BIOS所提供的HW信息。
结合ASL代码学习ACPI
1.从 _STA 说起.
_STA 描述了一个设备的当前状态,比如说它可以告诉操作系统某个device 是否存在,或者说,是否要show出来。具体参考ACPI spec 6.3.7(version 6.0)
这个object 描述了某个device 的当前状态,它可以是这三种情况:enabled, disabled 或者removed.
OSPM(其实就是OS) 在调用 INI 之前会先执行_STA 这个method. 先检测到它存在了,再去初始化它,不存在,也就没有初始化一说了。
如果某个device 下面,没有放这个_STA method ,我们默认它是存在并且正常工作的。
参数:
None
返回值:
Bit[0] 如果device 存在将会被置起
Bit[1] 如果device 被置起,并且decode 到相应的resource
Bit[2] 如果希望将其在UI中show出来,那么将这一位置起
Bit[3] 如果能正常工作,这一位会被置起。
Bit[4] 如果电池存在,置起这一位
Bit[31:5] 保留起来,以后用
// _STA (Status) // // This object returns the current status of a device. // // Arguments: (0) // None // Return Value: // An Integer containing a device status bitmap: // Bit 0 - Set if the device is present. // Bit 1 - Set if the device is enabled and decoding its resources. // Bit 2 - Set if the device should be shown in the UI. // Bit 3 - Set if the device is functioning properly (cleared if device failed its diagnostics). // Bit 4 - Set if the battery is present. // Bits 5-31 - Reserved (must be cleared). // Method(_STA) { If (LEqual(DPTF,1)){ Return(0x0F) } Else { Return(0x00) } }
动动手:一个小实验
这张图截自windows 设备管理器,他显示了系统下有哪些device.
如果你想其中某个隐藏起来,就在asl code 中找到它(比如通过hid). 然后在下面写一个_STA 方法,返回全0.
Device(RTC) // RTC { Name(_HID,EISAID("PNP0B00")) Name(_CRS,ResourceTemplate() { IO(Decode16,0x70,0x70,0x01,0x08) IRQNoFlags() {8} }) }
加几句,写成:
Device(RTC) // RTC { Name(_HID,EISAID("PNP0B00")) Name(_CRS,ResourceTemplate() { IO(Decode16,0x70,0x70,0x01,0x08) IRQNoFlags() {8} }) Method(_STA, 0) { Return (0) } }
然后,看看结果,是不是看不到RTC了?
FAQ?
谁去调用这些ASL code 中的这些method?
OS.
随便打开一份ACPI compatible (Linux , windows )的源代码,搜索_STA
ReactOS-0.3.14\drivers\bus\acpi\acpica\namespace\nsxfname.c (取自ReactOS)
有这么几行
/* * Get extra info for ACPI Device/Processor objects only: * Run the _STA, _ADR and, SxW, and _SxD methods. * * Note: none of these methods are required, so they may or may * not be present for this device. The Info->Valid bitfield is used * to indicate which methods were found and run successfully. */ /* Execute the Device._STA method */ Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus); if (ACPI_SUCCESS (Status)) { Valid |= ACPI_VALID_STA; } /* Execute the Device._ADR method */ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &Info->Address); if (ACPI_SUCCESS (Status)) { Valid |= ACPI_VALID_ADR; } /* Execute the Device._SxW methods */ Status = AcpiUtExecutePowerMethods (Node, AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS, Info->LowestDstates); if (ACPI_SUCCESS (Status)) { Valid |= ACPI_VALID_SXWS; }
2. OS 如何找到ACPI table?
通过RSDP 这个signature
/******************************************************************************* * * FUNCTION: Acpi_tb_scan_memory_for_rsdp * * PARAMETERS: Start_address - Starting pointer for search * Length - Maximum length to search * * RETURN: Pointer to the RSDP if found, otherwise NULL. * * DESCRIPTION: Search a block of memory for the RSDP signature * ******************************************************************************/ u8 * acpi_tb_scan_memory_for_rsdp ( u8 *start_address, u32 length) { u32 offset; u8 *mem_rover; /* Search from given start addr for the requested length */ for (offset = 0, mem_rover = start_address; offset < length; offset += RSDP_SCAN_STEP, mem_rover += RSDP_SCAN_STEP) { /* The signature and checksum must both be correct */ if (STRNCMP ((NATIVE_CHAR *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) == 0 && acpi_tb_checksum (mem_rover, RSDP_CHECKSUM_LENGTH) == 0) { /* If so, we have found the RSDP */ return (mem_rover); } } /* Searched entire block, no RSDP was found */ return (NULL); }
我要小额(2元)赞助,鼓励作者写出更好的教程
如果您认为本教程质量不错,读后觉得收获很大,预期工资涨幅能超过30%,不妨小额赞助我一下,让我有动力继续写出高质量的教程。
如果你有微信,请打开微信,使用“扫一扫”付款