acpi 学习笔记(6)

2019-08-30 19:23

/* Predefined (fixed) table indexes */ #define ACPI_TABLE_INDEX_DSDT (0) #define ACPI_TABLE_INDEX_FACS (1)

16, ACPI in Linux: 启动和初试化 /*{{{*/

0). NND,最先执行的ACPI函数不是acpi_early_init(),害我cscope查了半天!

start_kernel() > setup_arch() > acpi_boot_table_init() > acpi_table_init() > acpi_initialize_tables():

> acpi_boot_init() > acpi_table_parse(boot) > acpi_table_parse(fadt) > acpi_process_madt() > Note > acpi_table_parse(hpet)

acpi_process_madt()函数:

static void __init acpi_process_madt(void) {

#ifdef CONFIG_X86_LOCAL_APIC int error;

/** 寻找MADT表,找到的话,在其上运行acpi_parse_madt()函数 */ if ( !acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt) ) {

/*

* Parse MADT LAPIC entries -- 找到MADT中的LAPIC

* ADDRESS OVERRIDE结构, 再找MADT中的Local APIC结构, * 把找到的APIC的物理地址映射到FIXMAP保留的线性地址上 */

error = acpi_pase_madt_lapic_entries(); if (!error) { //success acpi_lacpi = 1;

#ifdef CONFIG_X86_GENERICARCH generic_bigsmp_probe(); #endif /*

* Parse MADT IO-APIC entries */

error = acpi_parse_madt_ioapic_entries(); if (!error) {

acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; acpi_irq_balance_set(NULL); acpi_ioapic = 1;

smp_found_config = 1; setup_apic_routing(); } }

if(error == -EINVAL) {

printk(\

disable_acpi(); } }

#endif//Local APIC return; }

这个函数是X86 SMP机器的关键代码,它负责找出系统中全部的LAPIC和IO-APIC。

先看看acpi_initialze_tables函数:

acpi_status __init acpi_initialize_tables(struct acpi_table_desc *initial_table_array, u32 initial_table_count, u8 allow_resice) {

acpi_physical_address rsdp_address; acpi_status status;

/* 如果initial_table_array为NULL,我们就申请一个; * 如果非NULL,说明它是整个ACPI表数组的首地址 *

* 其定义为:

* static struct acpi_table_desc initial_table[ACPI_MAX_TABLES] __initdata; * */

if (!initial_table_array) {

/*设置flag中的ACPI_ROOT_ALLOW_RESIZE*/

status = acpi_allocate_root_table(initial_table_count);

} else {

/* Root Table Array has been statically allocated * by the host.

* --什么意思?我猜测是:ACPI表数组(initial_tables)已经由BIOS静态分配好了, * 猜测是位于RAM中。 */

ACPI_MEMSET(initial_table_array, 0,

initial_table_count * sizeof(struct acpi_table_desc) );

/* XXX :

* 下面这3行代码很重要。在这个赋值操作发生之后,ACPI一直使用全局变量 * acpi_gbl_root_table_list来进行操作。 */

acpi_gbl_root_table_list.tables = initial_table_array;

acpi_gbl_root_table_list.size = initial_table_count; //表的个数,不是字节数 acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKOWN; }

/**

* 取得RSDP的地址。又分为EFI和非EFI两种情况,注意看实现方法 */

rsdp_address = acpi_os_get_root_pointer(); if (!rsdp_address)

return_ACPI_STATUS(AE_NOT_FOUND);

/**

* 已经有RSDP了,就意味着知道了RSDT或XSDT的地址,好了,取出所有的Tables! * XXX : Note,这步非常关键,因为它负责读取所有的ACPI Tables

*/

status = acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);

return_ACPI_STATUS(status); }

(Section 0)内核脚注:

===================

acpi_boot_table_init() and acpi_boot_init() called from setup_arch(), always: 1. checksums all tables; 2. enumerates lapics 3. enumerates io-apics

acpi_table_init() is seperate to allow reading SRAT without other side effects

side effects of acpi_boot_init: acpi_lapic = 1 if LAPIC found acpi_ioapic = 1 if IO-APIC found

if (acpi_lapic && acpi_ioapic) smp_found_config = 1; if acpi_blacklisted() acpi_disabled = 1; acpi_irq_model = ... ...


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

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

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

马上注册会员

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