} /*}}}*/
53, acpi_bus, acpi_device在Linux 2.6 Device Driver Model下的组织 /*{{{*/
acpi_scan_init()是个有__init属性的函数。
static int __init acpi_scan_init(void) {
int result;
struct acpi_bus_ops ops;
if (acpi_disabled) return 0;
memset(&ops, 0, sizeof(ops)); ops.acpi_op_add = 1; ops.acpi_op_start = 1;
/* 向核心注册acpi总线类型
* 就象在pci_driver_init()中注册PCI总线一样: * bus_register(&pci_bus_type)
*/
result = bus_register(&acpi_bus_type); if (result) {
/* We don't want to quit even if we failed to add * suspend/resume */
printk(KERN_ERR PREFIX \ }
/*
* Create the root device in the bus's device tree *
* 注意,acpi_root在drivers/acpi/bus.c中定义:struct acpi_device *acpi_root * (我猜测)它是ACPI namespace的root node。 */
result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, ACPI_BUS_TYPE_SYSTEM, &ops); if (result) goto Done;
/*
* Enumerate devcies in the ACPI namespace *
* 从acpi_root开始,枚举namespace中的所有对象 */
result = acpi_bus_scan_fixed(acpi_root); if (!result)
result = acpi_bus_scan(acpi_root, &ops);
if (result)
acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
Done:
return result; } /*}}}*/
56, Local APIC的Base Address
是个物理地址。
#ifdef CONFIG_X86_LOCAL_APIC
static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; #endif
#define APIC_DEFAULT_PHYS_BASE 0xfee00000
而start_kernel > setup_arch > acpi_boot_init > acpi_process_madt > acpi_table_parse/acpi_parse_madt中:
if(madt->address) {
acpi_lapic_addr = (u64) madt->address;
printk( \ }
61, ACPI如何映射一个table
/*{{{*/
acpi_boot_table_init() > acpi_table_init() > acpi_initialize_tables() :
acpi_physical_address rsdp_address = acpi_os_get_root_pointer();
status = acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
> acpi_tb_install_table() :
struct acpi_table_header *table;
table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
//FIXME: 为什么要有ioremap和__acpi_map_table()两种方式?
void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size) {
if (phys > ULONG_MAX) {
printk(KERN_ERR PREFIX \
return NULL; }
if (acpi_gbl_permanent_mmap) /*
* ioremap checks to ensure this is in reserved space */
return ioremap((unsigned long)phys, size); else
return __acpi_map_table((unsigned long)phys, size); }
/*}}}*/
62, Questions and (possibly) Answers
1. Linux的initial_tables变量从未被赋值,所以acpi_initialize_tables()函数 中的if判断永远为真
//FIXME: is it a trivial BUG?