efi的sys文件系统接口
2017-02-08 16:19
423 查看
在driver/firmware/efi/efi.c 中通过subsys_initcall(efisubsys_init);来初始化efisubsys
static int __init efisubsys_init(void)
{
int error;
if (!efi_enabled(EFI_BOOT))
return 0;
/* We register the efi directory at /sys/firmware/efi */
efi_kobj = kobject_create_and_add("efi", firmware_kobj);
if (!efi_kobj) {
pr_err("efi: Firmware registration failed.\n");
return -ENOMEM;
}
error = generic_ops_register();
if (error)
goto err_put;
if (efi_enabled(EFI_RUNTIME_SERVICES))
efivar_ssdt_load();
error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
if (error) {
pr_err("efi: Sysfs attribute export failed with error %d.\n",
error);
goto err_unregister;
}
error = efi_runtime_map_init(efi_kobj);
if (error)
goto err_remove_group;
/* and the standard mountpoint for efivarfs */
error = sysfs_create_mount_point(efi_kobj, "efivars");
if (error) {
pr_err("efivars: Subsystem registration failed.\n");
goto err_remove_group;
}
}
在efisubsys_init 中会通过kobject_create_and_add在/sys/firmware/下建立efi的目录,然后会通过sysfs_create_group来efi_subsys_attr_group group
static struct attribute_group efi_subsys_attr_group = {
.attrs = efi_subsys_attrs,
.is_visible = efi_attr_is_visible,
};
继续看efi_subsys_attrs
static struct attribute *efi_subsys_attrs[] = {
&efi_attr_systab.attr,
&efi_attr_fw_vendor.attr,
&efi_attr_runtime.attr,
&efi_attr_config_table.attr,
&efi_attr_fw_platform_size.attr,
NULL,
};
在efisubsys_init 中通过sysfs_create_mount_point 来创建efivars的mountpoint。
而efi_runtime_map_init 则为每一段efi.memmap 创建sys接口,而所有的接口都是放在map_entries 这个list中
int __init efi_runtime_map_init(struct kobject *efi_kobj)
{
int i, j, ret = 0;
struct efi_runtime_map_entry *entry;
efi_memory_desc_t *md;
if (!efi_enabled(EFI_MEMMAP))
return 0;
map_entries = kzalloc(efi.memmap.nr_map * sizeof(entry), GFP_KERNEL);
if (!map_entries) {
ret = -ENOMEM;
goto out;
}
i = 0;
for_each_efi_memory_desc(md) {
entry = add_sysfs_runtime_map_entry(efi_kobj, i, md);
if (IS_ERR(entry)) {
ret = PTR_ERR(entry);
goto out_add_entry;
}
*(map_entries + i++) = entry;
}
return 0;
out_add_entry:
for (j = i - 1; j >= 0; j--) {
entry = *(map_entries + j);
kobject_put(&entry->kobj);
}
out:
return ret;
}
因此实际我们可以看到如下:
[root@CentOS efi]# pwd
/sys/firmware/efi
[root@CentOS efi]# ls
efivars fw_platform_size systab vars
static int __init efisubsys_init(void)
{
int error;
if (!efi_enabled(EFI_BOOT))
return 0;
/* We register the efi directory at /sys/firmware/efi */
efi_kobj = kobject_create_and_add("efi", firmware_kobj);
if (!efi_kobj) {
pr_err("efi: Firmware registration failed.\n");
return -ENOMEM;
}
error = generic_ops_register();
if (error)
goto err_put;
if (efi_enabled(EFI_RUNTIME_SERVICES))
efivar_ssdt_load();
error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
if (error) {
pr_err("efi: Sysfs attribute export failed with error %d.\n",
error);
goto err_unregister;
}
error = efi_runtime_map_init(efi_kobj);
if (error)
goto err_remove_group;
/* and the standard mountpoint for efivarfs */
error = sysfs_create_mount_point(efi_kobj, "efivars");
if (error) {
pr_err("efivars: Subsystem registration failed.\n");
goto err_remove_group;
}
}
在efisubsys_init 中会通过kobject_create_and_add在/sys/firmware/下建立efi的目录,然后会通过sysfs_create_group来efi_subsys_attr_group group
static struct attribute_group efi_subsys_attr_group = {
.attrs = efi_subsys_attrs,
.is_visible = efi_attr_is_visible,
};
继续看efi_subsys_attrs
static struct attribute *efi_subsys_attrs[] = {
&efi_attr_systab.attr,
&efi_attr_fw_vendor.attr,
&efi_attr_runtime.attr,
&efi_attr_config_table.attr,
&efi_attr_fw_platform_size.attr,
NULL,
};
在efisubsys_init 中通过sysfs_create_mount_point 来创建efivars的mountpoint。
而efi_runtime_map_init 则为每一段efi.memmap 创建sys接口,而所有的接口都是放在map_entries 这个list中
int __init efi_runtime_map_init(struct kobject *efi_kobj)
{
int i, j, ret = 0;
struct efi_runtime_map_entry *entry;
efi_memory_desc_t *md;
if (!efi_enabled(EFI_MEMMAP))
return 0;
map_entries = kzalloc(efi.memmap.nr_map * sizeof(entry), GFP_KERNEL);
if (!map_entries) {
ret = -ENOMEM;
goto out;
}
i = 0;
for_each_efi_memory_desc(md) {
entry = add_sysfs_runtime_map_entry(efi_kobj, i, md);
if (IS_ERR(entry)) {
ret = PTR_ERR(entry);
goto out_add_entry;
}
*(map_entries + i++) = entry;
}
return 0;
out_add_entry:
for (j = i - 1; j >= 0; j--) {
entry = *(map_entries + j);
kobject_put(&entry->kobj);
}
out:
return ret;
}
因此实际我们可以看到如下:
[root@CentOS efi]# pwd
/sys/firmware/efi
[root@CentOS efi]# ls
efivars fw_platform_size systab vars
相关文章推荐
- 应用程序访问内核的新接口/sys文件系统
- cpu topology sys文件系统接口
- linux驱动层到应用层的重要接口sys文件系统---/sys目录详解
- 驱动设备模型---sys文件系统之最后总结
- 文件系统,dev接口,文件压缩与解压
- Linux 内核/sys 文件系统介绍
- Linux系统配置文件 /etc/sysconfig详解
- Linux网络管理员手册(5) 第五章 配置TCP/IP网络 proc文件系统 设置主机名 分配IP地址 IP的接口配置 以太网接口
- Linux 内核/sys 文件系统介绍
- 通过/sys/文件接口操作IO端口
- Linux 内核/sys 文件系统介绍
- 使用Spring中的Resource接口隔离对文件系统的依赖
- Intel Flash的驱动实现及提供给文件系统Flash File System的一些接口
- Linux 内核/sys 文件系统介绍[转]
- 调用 系统蓝牙接口 发送文件
- Linux 内核/sys 文件系统之uevent
- sys文件系统总结,,
- 系统sys文件丢失的解决,请高手给个解释哦
- 什么是sys文件系统
- PVFS2 源代码分析之用户系统接口src/client/sysin/sys-get-eattr.c状态机代码