efi_init->uefi_init
uefi_init 调用efi_config_parse_tables
static int __init uefi_init(void)
{
retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
sizeof(efi_config_table_64_t), NULL);
}
在efi_config_parse_tables 中首先调用match_config_table ,看common table中是否已经包含
要添加的表,如果已经有了,则不能重复添加
int __init efi_config_parse_tables(void *config_tables, int count, int sz,
efi_config_table_type_t *arch_tables)
{
void *tablep;
if (!match_config_table(&guid, table, common_tables))
match_config_table(&guid, table, arch_tables);
pr_cont("\n");
set_bit(EFI_CONFIG_TABLES, &efi.flags);
}
当成功添加后在efi.flags 中设置EFI_CONFIG_TABLES,说明kernel 可以使用uefi的config table。
在match_config_table 中主要是efi_guidcmp来比较common_tables 中预定义的GUID是否相等,如果相等
就将对应的项赋值.
static __init int match_config_table(efi_guid_t *guid,
unsigned long table,
efi_config_table_type_t *table_types)
{
int i;
if (table_types) {
for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
if (!efi_guidcmp(*guid, table_types[i].guid)) {
*(table_types[i].ptr) = table;
if (table_types[i].name)
pr_cont(" %s=0x%lx ",
table_types[i].name, table);
return 1;
}
}
}
return 0;
}
static __initdata efi_config_table_type_t common_tables[] = {
{ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
{ACPI_TABLE_GUID, "ACPI", &efi.acpi},
{HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
};
这样当kernel中调用acpi_os_get_root_pointer 获得root pointer的时候,会首先判读efi_enabled(EFI_CONFIG_TABLES)
这个我们前面已经设置了,然后就会返回efi.acpi20 作为root pointer,这个也在前面的match_config_table中赋值.
acpi_physical_address __init acpi_os_get_root_pointer(void)
{
#ifdef CONFIG_KEXEC
if (acpi_rsdp)
return acpi_rsdp;
#endif
if (efi_enabled(EFI_CONFIG_TABLES)) {
if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
return efi.acpi20;
else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
return efi.acpi;
else {
printk(KERN_ERR PREFIX
"System description tables not found\n");
return 0;
}
} else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
acpi_physical_address pa = 0;
acpi_find_root_pointer(&pa);
return pa;
}
return 0;
}
uefi_init 调用efi_config_parse_tables
static int __init uefi_init(void)
{
retval = efi_config_parse_tables(config_tables, efi.systab->nr_tables,
sizeof(efi_config_table_64_t), NULL);
}
在efi_config_parse_tables 中首先调用match_config_table ,看common table中是否已经包含
要添加的表,如果已经有了,则不能重复添加
int __init efi_config_parse_tables(void *config_tables, int count, int sz,
efi_config_table_type_t *arch_tables)
{
void *tablep;
if (!match_config_table(&guid, table, common_tables))
match_config_table(&guid, table, arch_tables);
pr_cont("\n");
set_bit(EFI_CONFIG_TABLES, &efi.flags);
}
当成功添加后在efi.flags 中设置EFI_CONFIG_TABLES,说明kernel 可以使用uefi的config table。
在match_config_table 中主要是efi_guidcmp来比较common_tables 中预定义的GUID是否相等,如果相等
就将对应的项赋值.
static __init int match_config_table(efi_guid_t *guid,
unsigned long table,
efi_config_table_type_t *table_types)
{
int i;
if (table_types) {
for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
if (!efi_guidcmp(*guid, table_types[i].guid)) {
*(table_types[i].ptr) = table;
if (table_types[i].name)
pr_cont(" %s=0x%lx ",
table_types[i].name, table);
return 1;
}
}
}
return 0;
}
static __initdata efi_config_table_type_t common_tables[] = {
{ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
{ACPI_TABLE_GUID, "ACPI", &efi.acpi},
{HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
};
这样当kernel中调用acpi_os_get_root_pointer 获得root pointer的时候,会首先判读efi_enabled(EFI_CONFIG_TABLES)
这个我们前面已经设置了,然后就会返回efi.acpi20 作为root pointer,这个也在前面的match_config_table中赋值.
acpi_physical_address __init acpi_os_get_root_pointer(void)
{
#ifdef CONFIG_KEXEC
if (acpi_rsdp)
return acpi_rsdp;
#endif
if (efi_enabled(EFI_CONFIG_TABLES)) {
if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
return efi.acpi20;
else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
return efi.acpi;
else {
printk(KERN_ERR PREFIX
"System description tables not found\n");
return 0;
}
} else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
acpi_physical_address pa = 0;
acpi_find_root_pointer(&pa);
return pa;
}
return 0;
}