ACPI – the Advanced Configuration & Power Interface. ACPI是OS,BIOS和硬件之间的抽象层。它允许OS和平台独立的发展,比如新的OS可以控制老的平台,老的OS也可以控制新的平台而不需要额外的修改。ACPI的基本结构图如下:

计算机领域的一个基本方法是增加一个抽象层,从而使得抽象层的上下两层独立的发展,ACPI事实上也是借鉴类似的思想。ACPI的抽象主要是通过ACPI表中提供的信息来实现,这些信息包括ACPI寄存器、AML代码、配置信息等。ACPI寄存器,描述了和ACPI相关的寄存器。OS可以直接从ACPI表中取得这些寄存器的信息,因此不必了解具体的硬件配置。

AML代码,一种类C的代码。由BIOS提供,OS的AML解释器(在Linux中叫ACPI CA)解释执行这些代码。这是ACPI抽象层的关键,下面会详细介绍。

配置信息,ACPI包含的配置信息很多,比如多处理器配置信息(MADT)、NUMA配置信息(SRAT、SLIT)、高精度定时器(HPET)等。

AML代码是抽象的关键。为了消除平台相关性,BIOS把平台相关的操作用AML代码来实现。OS不需要知道平台细节,它只是解释执行这些代码,在解释执行的过程中平台相关的操作就被执行了。ACPI规范定义了一些标准的AML函数,OS解释执行一个这样的标准函数就可以实现特定的功能。举个例子:

Scope (_SB.PCI0.LPC) { OperationRegion (LPCS, PCI_Config, 0x00, 0x0100) Field (LPCS, AnyAcc, NoLock, Preserve) { Offset (0x60),                                            PIRA,   8, } } Device (LNKA) {                     Method (_DIS, 0, NotSerialized) {                                           Or (\_SB.PCI0.LPC.PIRA, 0x80, \_SB.PCI0.LPC.PIRA) } }

比如我们想禁止LNKA设备,ACPI规范定义了OS必须执行此设备的_DIS函数。从硬件的角度来讲,禁止LNKA设备需要将某个PCI设备的配置空间的寄存器0×60的最高位置上。OS不需要知道硬件的细节,它解释执行_DIS函数即可。上面的代码就是AML代码,由BIOS提供,语句‘Or (\_SB.PCI0.LPC.PIRA, 0×80, \_SB.PCI0.LPC.PIRA)’实际上就是给寄存器\_SB.PCI0.LPC.PIRA置上最高位, 而PIRA就是PCI设备LPC的配置空间的寄存器0×60。从此段代码我们可以明显的看出BIOS以AML代码的形式隐藏(抽象)了硬件的细节,从而使得OS看到的是一个平台无关的硬件。

更多的ACPI预定义的函数可以在ACPI规范中找到,可以在下载最新的规范。

Linux/ACPI实现中使用的AML解释器是ACPICA -the ACPI Component Architecture. 可以从得到。它包含一个AML解释器(Linux kernel包含了这个解释器,很多其他OS也是如此,比如BSD、opensolaris等),一个编译器(将ACPI Source Language (ASL)编译成AML代码)和一些测试工具。

最新的Linux/ACPI的代码可以使用git在得到。

ACPI是Intel(i386,x86_64,IA64)平台的标准固件规范,绝大部分OS需要从BIOS得到的信息都可以从ACPI得到,并且现在的趋势是未来的任何新的特性相关的信息都只能从ACPI得到。ACPI的内容庞杂,学习ACPI至少可以帮助我们理解:配置信息。这些信息从legacy PNP设备的配置,到多处理器,到NUMA,比如现在的Multiple Core的信息就只能从ACPI得到。Linux启动很多代码就是处理这些配置信息,比如APIC,IOAPIC设置等。

ACPI相关设备。主要是笔记本电脑相关的设备,包括电源按钮,电池,外接电源,风扇,热键等。

底层硬件。比如PCI中断路由,chipset(主要是南桥PCI-to-LPC bridge)操作等。

电源管理。ACPI定义的电源管理包括CPU的电源管理(调频率P-state,idle C-state,throtting T-state),设备电源管理(D-state),系统电源管理(Suspend-to-Ram, Suspend-to-Disk, power off)等。

设备热插拔。ACPI用一种统一的方式来描述设备的热插拔,这样的设备从单一的PCI设备,到笔记本电脑的Docking Station,到整个PCI hierarchy,CPU,Memory,甚至整个NUMA节点。

可以说要理解现代PC平台必须了解ACPI。

首先可以看看是否这是一个regression,如果以前版本的Linux kernel可以工作,但新的不行,则是一个regression,可以测试不同的kernel从而找出哪个版本引入了bug。使用git-bisect是一个好的选择,它可以帮你定位到哪个patch导致了regression。一些git-bisect相关的资料如下:

试试kernel参数”acpi=off”,如果此参数没有带来任何改变,那么这不是一个ACPI bug。反之,则这很可能是一个ACPI bug。 确定了是一个ACPI bug后,我们还有其他一些参数来更进一步的区分到底是ACPI哪个部分的bug。

acpi=ht这个参数和"acpi=off"几乎一样,它禁止了除多处理器配置相关的内容以外的所有ACPI功能。如果acpi=off正常,但acpi=ht 不正常, 则解析ACPI 表或者Linux SMP的代码有bug.

pci=noacpi禁止使用ACPI来处理任何PCI相关的内容,包括PCI root bus的枚举和PCI设备中断路由。

acpi=noirq禁止使用ACPI来处理PCI设备中断路由,和pci=noacpi的区别是它允许使用ACPI来枚举PCI root bus.

pnpacpi=off禁止使用ACPI来枚举PNP设备,比如串口、PS2键盘鼠标等。

noapic禁止使用io-apic来做设备中断路由,这样做的效果之一是ACPI返回的中断路由表将是针对PIC(8259)的。

nolapic禁止使用Local-APIC和IO-APIC。

出现中断问题的可能性很多,比如驱动程序有bug。由ACPI导致的最常见的中断问题是kernel打出:”irqXX: nobody cared!”。这意味着kernel收到一个中断,但是没有驱动程序来处理此中断。Kernel会将此中断禁止,从而导致挂在此中断上的所有设备都停止工作。pci=noacpi, acpi=noirq, pnpacpi=off, noapic, nolapic这些参数可以帮助隔离一些问题。另外一个有用的参数是”irqpoll”,出现上面的中断问题时,它可以使kernel自动探测哪个设备发出了中断。这个参数对于调试那些中断路由有问题的系统很有用。

STR的一个常见问题是Resume回来后黑屏,但是系统并没有死掉,比如可以通过网络访问系统或者键盘灯工作正常。可以试试kernel参数acpi_sleep=s3_bios/s3_mode,它会尝试将显示器打开。如果不行可以试试vbetools(),在resume回来后输入 $ vbetool post 为了方便,你可以在你的STR脚本中调用此命令。

STR的另一个常见问题是系统没法resume回来,你可以试试acpi_sleep=s3_beep。如果你听不到电脑的扬声器产生的声音,那么resume的代码完全没被执行。这可能是BIOS的原因,也可能是Linux的原因,目前还没有太好的办法处理。反之,很有可能是Linux driver的原因,你可以尝试尽可能少的加载驱动程序,只保留最基本的驱动,比如硬盘驱动。

TBD

参数是acpi.debug_level and acpi.debug_layer。如果打开debug参数,ACPI可以产生很多详细的运行输出。这些输出可以帮助我们定位出错的原因。

对于debug_layer和debug_level,include/acpi/acoutput.h里面包含了很多值,这些值决定了Linux/ACPI输出信息的详细程度和内容范围。acpi.debug_level和 acpi.debug_layer是kernel参数,也可以在系统运行时改变这些值,它们是/sys/module/acpi/parameters/debug_{level,layer}。

注意,这些输出信息可能很快就将kernel的ring buffer用完,你可能需要使用log_buf_len=XY来增加ring buffer的大小。使用serial console (Documentation/serial-console.txt)来得到kernel输出是一个好的方法。如果你的笔记本电脑没有串口,可以试试netconsole (Documentation/networking/netconsole.txt)。

DSDT (Differentiated System Description Table)是一个主要的ACPI表,它包含了很多AML代码。因为BIOS的bug,这些代码本身可能有错。Linux提供的一种方法能让你使用定制的DSDT表,这对于调试很有帮助。让kernel使用定制的DSDT步骤如下:

首先要得到原始的DSDT表(后面的章节会介绍acpidump等工具):     $ acpidump > acpidump.out     $ acpixtract DSDT acpidump > DSDT.dat     这样我们就得到了DSDT表的二进制文件,将它反汇编     $ iasl -d DSDT.dat     我们会得到一个AML代码文件,你可以修改它     $ vi DSDT.dsl     然后重新编译     $ iasl -tc DSDT.dsl     把它拷贝到kernel source中     $ cp DSDT.hex $SRC/include/

加入下面几行到你的kernel配置文件(.config):

CONFIG_STANDALONE=n CONFIG_ACPI_CUSTOM_DSDT=y CONFIG_ACPI_CUSTOM_DSDT_FILE=”DSDT.hex”

编译kernel,运行,你的dmesg中应该有如下输出: Table [DSDT] replaced by host

Linux/ACPI社区使用kernel bugzilla来跟踪bug 。。这个网站主要是跟踪base kernel的bug,如果你有特定发行版的bug,不要发到这个网站。Linux/ACPI有自己的邮件列表(),你也可以在那里讨论问题。另外,Intel的Linux/ACPI组也有一个邮件地址(),如果你的问题不方便公开,可以发到这儿。

如果你报告一个bug,请提交如下信息:产生bug的kernel版本

以前的kernel有没有这样的bug。如果这是一个regression,最近可以工作的kernel版本是什么。如果你能使用git-bisect找到哪个patch带来regression,那问题基本上就等于解决了。

出错的kernel和最近工作kernel的dmesg信息。你可能需要使用serial console来得到这些信息。

如果这是中断相关的问题,可能的话请提供kernel出错和工作的时候/proc/interrupts的输出。/sbin/lspci –vvv和/sbin/lspci -xxx的输出也很有用。

请提供acpidump的输出。Acpidump是一个工具,它可以将系统中的ACPI表打出来。你可以在找到这个工具。注意acpidump输出的是BIOS的表,不同的BIOS版本可能会有不同的表。

如果我们发现BIOS有问题,我们可以将此系统列入黑名单,在这种情况下需要提供dmidecode(通常在/usr/sbin/下)工具的输出。

产生bug的kernel配置文件

,按照包里面的README编译。使用步骤如下:导出所有的表,这些表都是二进制的 $ acpidump > acpidump.out

上面的输出包含了很多个ACPI表,如果你希望将它们分离开,使用 $ acpixtract -a acpidump.out

反汇编某个表 $ iasl -d TABLE.dat 这样就得到类C的AML代码。

ACPI in Linux – Myths vs. Reality(OLS 2007) paper:  presentation:

ACPI in Linux – Architecture, Advances, and Challenges(OLS 2005) paper:  presentation:

The State of ACPI in the Linux Kernel(OLS 2004)

Suspend/resume的稳定性。Suspend-to-ram在很多笔记本电脑上不能工作。很多驱动程序没有实现.suspend/.resume方法或者实现有问题。

Hotkey的支持。很多笔记本电脑厂商使用完全不同的方法来支持hotkey,现在Linux支持IBM,Asus,Toshiba等。但是还有很多厂商的不支持,即使支持的厂商也有很多笔记本型号不支持。

运行时设备电源管理。Linux还缺乏一个框架在系统运行时对设备进行电源管理,例如在某个设备空闲时将它关闭而不影响整个系统的运行。

Device model方面的改进。Linux仍然缺乏一个好的机制将ACPI设备和它对应的物理设备统一起来处理。

Bugzilla上有很多ACPI的bug

linux acpi 代码,ACPI简介 Linux相关推荐

  1. linux系统网络编程简介,Linux网络编程入门

    本文是在Linux环境下编写网络程序,有必要介绍下实验环境. 1.如右侧环境所示分为两上下两个部分, 上半部分是文件管理,可以进行创建文件.删除文件以及文件中编写程序等. 下半部分是Linux系统命令 ...

  2. Linux内核代码宏定义,Linux Kernel源代码中与段有关的重要宏定义

    __init, __initdata等属性标志,是要把这种属性的代码放入目标文件的.init.text节,数据放入.init.data节──这一过程是通过编译内核时为相关目标平台提供了xxx.lds链 ...

  3. linux静态代码检查工具,linux下splint检测C语言代码质量

    在linux下并没有pclint,可以使用splint代替.splint使用一.splint介绍splint是一个静态检查C语言程序安全弱点和编写错误的工具.splint会进行多种常规检查,包括未使 ...

  4. linux 进程代码,怎样从Linux终端管理进程:10个你必须知道的命令

    Linux终端有一系列有用的命令.它们可以显示正在运行的进程.杀死进程和改变进程的优先级.本文列举了一些经典传统的命令和一些有用新颖的命令.本文提到的命令会实现某个单一功能.它们可以结合起来--这也是 ...

  5. linux截屏软件,简介Linux截屏工具:import

    现在很多人都安装了Linux,在应用Linux会遇到很多问题,本文为你详细介绍Linux截屏工具,为你在学习Linux截屏工具时起一定的作用.在Linux中,最简单的截屏工具莫过于import了. 几 ...

  6. linux c代码调试工具,在 Linux 中调试 C 程序的福音——gdb

    如果你是 C/C++ 程序员,或者使用 Fortran 和 Modula-2 编程语言开发软件,那么你将会很乐意知道有这么一款优秀的调试器 - GDB - 可以帮你更轻松地调试代码 bug 以及其它问 ...

  7. linux保存压缩程序输出,Linux压缩zip文件

    1. Linux下zip工具简介 Linux上使用命令行版的zip压缩工具创建zip压缩文件. 2. 安装zip工具 以CentOS7.5为例,默认情况下,最小化安装并没有包括zip套件. [root ...

  8. linux命令大全chm版本,Linux命令大全手册下载

    linux命令大全chm版是精心修改版,去除了官方原版的许多错误,以及未来得及更新的部分,实用性很强,对于正在掌握linux系统的程序员们来说,是开发之前必须学会的东西,操作方便.检测迅速,举一反三靠 ...

  9. linux 禁用cpu的acpi,Linux中的ACPI和APIC

    Linux中的ACPI和APIC 发布时间:2007-12-21 01:00:21来源:红联作者:qtsmy 今天一朋友笔记本系统启动有问题,用的是ubuntu,据说是启动速度越用越慢,今天是完全进不 ...

最新文章

  1. RabbitMQ消息应答------ack机制
  2. 字节增强java_提高byte的效率
  3. MyBatis3 用log4j在控制台输出 SQL----亲测,真实可用
  4. linux数据库mysql的安装
  5. mysql group by自定义_mysql – GROUP BY和自定义顺序
  6. emmc固件开发_UP2开发板简易开箱(二)
  7. 用 cairo 实现跨平台图形
  8. Chrome 将内置 QR 扫码共享页面功能
  9. 老公想入手一块10万左右的手表有哪些推荐?
  10. .net程序员写业务代码需要注意的地方
  11. 移植u-boot.2012.04.01
  12. 3.1.2 Score Inflation 总分
  13. 【uni-app】第三方ui组件推荐引入的方法
  14. opengl——贴图
  15. Java语言 Timer 定时器的四种使用方式
  16. 图片切换马赛克动画效果
  17. java神雕侠侣1古墓情缘游戏攻略_神雕侠侣古墓派后期攻略讲解
  18. Python实验、函数和代码复用
  19. 什么原因让你对程序员失去了往日的热情?
  20. mysql数据库练习作业

热门文章

  1. 在哪里刷题_击穿刷题马太效应,用20%的时间,快速刷出80%的成绩!高三冲刺必看!...
  2. 金三银四面试必问:AQS了解吗?
  3. 技术转管理,就要丢掉技术吗?
  4. Oracle密码过期,取消密码天数限制
  5. chatgpt赋能python:Python编程爱好者必备:如何参加线上比赛
  6. 千元蓝牙耳机哪些比较好用?四款高性价比蓝牙耳机测评
  7. 计算机对比度亮度调整,电脑对比度和亮度多少合适_电脑最佳的亮度和对比度-win7之家...
  8. 使用QTP11.0的过程中,常见的部分问题解决方法(持续更新...)
  9. 将24小时进制转化为12小时进制
  10. 详解Node.js开发中不可或缺的7个库