acpi 学习笔记(5)

2019-08-30 19:23

这样,当调用完毕,(E820NR)这块内存就保存了entries数目。

Linu引导时,设置memmap的调用路径是:

start_kernel() > setup_arch() > memory_setup() > sanitize_e820_map(E820_MAP, &E820_MAP_NR)

> copy_e820_map(E820_MAP, E820_MAP_NR)

其中E820_MAP和E820_MAP_NR的定义:

#define E820_MAP_NR (*(char*) (PARAM+E820NR))

#define E820_MAP ((struct e820entry *) (PARAM+E820MAP))

//FIXME:PARAM是什么意思? 猜测是Linux用来保存boot parameters的页面,见arch/i386/kernel/ head.S

其中E820NR和E820MAP是两个16位的内存地址,已经在setup.S中调用bios call时设置好了。见上边 的笔记。

/**

* 一个个range地添加从bios获得的内存布局信息 *

* 作者注释:

* =========

* 我们检查一下从BIOS获得的memmap是不是至少包含2个区间。 因为setup.S中的探测结果可能不

* 那么完美,而我们又知道大多数PC机有两个内存区域:一个从0到640k,另一个从1M往上。 *

* 如果BIOS得来的结果是正确的,那么我们就使用它给的memmap;如果不正确,我们就自己伪造

* 一个(案,即是在这里返回-1,让调用者machine_specific_memory_setup()去伪造。) */

int __init copy_e820_map(struct e820entry *biosmap, int nr_map) {

/* 只有一个,或者竟然是负的?那么就忽略它 */ if (nr_map < 2) return -1;

do {

unsigned long long start = biosmap->addr; unsigned long long size = bisomap->size; unsigned long long end = start + size; unsigned long type = biosmap->type; ...

if ( type = E820_RAM ) { //是ACPI中可用的RAM类型,那么我们就设置它 if (start < 0x100000ULL && end > 0xA0000ULL) { if (start < 0xA0000ULL)

add_memory_region(start, 0xA0000ULL-start, type); if (end <= 0x100000ULL) continue;

start = 0x100000ULL;

size = end - start; } }

/* 添加一个Memory Range。

* 注意! e820这个全局变量,就是在该函数中设置的值! */

add_memory_region(start, size, type);

} while (biosmap++, --nr_map);

return 0; }

这个copy_e820_map()函数执行完毕,则memory map就已经设置到全局变量e820中了。

14. ACPI Namespace 和 Definition Block

只有Unload一个Definition Block时,name才会从名空间中移除。

只有Load/Unload 定义块 时,Namespace中内容才可能改变。

Definition Block只可能出现在DSDT和SSDT(s)中。其它表没有。 Linux内核中加载namespace的

函数为acpi_tb_load_namespace(),其注释说:Load the namespace from the DSDT and all SSDTs/PSDTs found in the RSDT/XSDT.

(FIXME: 就Dell Optiplex 745机器用acpidump,acpixtract,iasl -d反汇编出来的.dsl 来看,一个DSDT或SSDT只有一个DefinitionBlock。 不知道这是否是ACPI规范了的)

Name的命名约定:

1. 每个Name都是固定的32bit(4字节)大小。

2. Name的第一个字符必须是'A'-'Z',或者下划线'_'

3. Name不足4个字节的,ASL编译器会对它进行填充。 惯用的填充方式就是在 结尾填充下划线'_'。

4. 以下划线'_'开头的Name是由ACPI规范预留的,也就是说,只有ACPI规范定义了 一个以'_'开头的Name, 供应商才能提供它。 不允许自己定义以'_'开头的Name

5. 以'\\'开头的Name,表示引用namespace的根。('\\'不算在4字节长度之内)

6. 以'^'开头的Name,表示引用本namespace的parent。('^'不算在4字节长 度之内)

预定义了的namespaces(见规范3.0之5.3.1部分)

\\_GPE : General events in GPE register block \\_PR : ACPI 1.0 Processor Namespace.

\\_SB : All Device/Bus Objects under this namespace \\_SI : System Indicator.

\\_TZ : ACPI 1.0 Thermal Zonen namespace.

15. Linux至少加载ACPI的3个Tables: FADT, FACS, DSDT (RSDT不算在内)

见acpi_tb_tables_loaded()函数:

if (acpi_gbl_root_table_list.count >= 3) { return (TRUE); else

return (FALSE);

其中DSDT和FACS在acpi_gbl_root_table_list数组中的索引是固定的,DSDT是0, FACS是1:


acpi 学习笔记(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:脉脉 从中国社会实际出发的典型案例

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: