没有整个框架去细看OS对ACPI处理是不好的

前言

现在已经很久没有去更新ACPI表,整日忙于工作。工作上大体上是没有任何意义,学习不到底层上的原理只能抽空看看了。越工作越觉得自己知识深度可宽度都不行。

我在前面acpi_early_init 中看到了,OS会开辟一段ACPI表的空间创建,创建表头,创建信号量等一系列上的操作。acpi_init对这些函数进行了进一步的处理。

如果直接去看acpi_init函数实在是太过于宽泛了

init_acpi_device_notify(); 初始化ACPI设备的通知系统。
acpi_bus_init():一个ACPI(高级配置和电源接口)总线初始化函数

pci_mmcfg_late_init():初始化PCI多功能配置空间。
acpi_iort_init():初始化中断对象资源表(IORT)。
acpi_scan_init():扫描ACPI设备。
acpi_ec_init():初始化嵌入式控制器。
acpi_debugfs_init():设置ACPI的调试文件系统条目。
acpi_sleep_proc_init():初始化电源管理的睡眠过程。
acpi_wakeup_device_init():初始化可以唤醒系统的设备。
acpi_debugger_init():初始化ACPI调试器。
acpi_setup_sb_notify_handler():设置系统总线通知的处理程序。

这些函数每一个单独拿出来,那都是一个大模块,所以让我们一点拨开去看吧。

acpi_bus_init

 实际上盖模块还是需要继续分解,本文按照一层层的打开去分析。

1. ACPI OS 初始化

acpi_os_initialize1();

  • 这个模块负责初始化 ACPI 操作系统服务。acpi_os_initialize1() 函数执行与操作系统相关的 ACPI 初始化工作。

以下是该函数的详细内容 

acpi_status __init acpi_os_initialize1(void)
{
    // 分配一个工作队列用于处理 ACPI 相关的任务,队列名称为 "kacpid"
    kacpid_wq = alloc_workqueue("kacpid", 0, 1);
    
    // 分配一个工作队列用于处理 ACPI 通知事件,队列名称为 "kacpi_notify"
    kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
    
    // 分配一个有序工作队列用于处理 ACPI 热插拔事件,队列名称为 "kacpi_hotplug"
    kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
    
    // 检查 kacpid_wq 是否分配成功,如果失败则触发内核错误
    BUG_ON(!kacpid_wq);
    
    // 检查 kacpi_notify_wq 是否分配成功,如果失败则触发内核错误
    BUG_ON(!kacpi_notify_wq);
    
    // 检查 kacpi_hotplug_wq 是否分配成功,如果失败则触发内核错误
    BUG_ON(!kacpi_hotplug_wq);
    
    // 调用函数初始化 ACPI 操作系统兼容性字符串
    acpi_osi_init();
    
    // 返回 AE_OK,表示初始化成功
    return AE_OK;
}

上述代码中一共提及到了两个比较重要的点 alloc_workqueue,acpi_osi_init。 置于工作队列,这里只做了一个简单的介绍,这不是我目前学习的重点。

workqueue是对内核线程封装的用于处理各种工作项的一种处理方法, 由于处理对象是用链表拼接一个个工作项, 依次取出来处理, 然后从链表删除,就像一个队列排好队依次处理一样, 所以也称工作队列,所谓封装可以简单理解一个中转站, 一边指向“合适”的内核线程, 一边接受你丢过来的工作项, 用结构体 workqueue_srtuct表示, 而所谓工作项也是个结构体 --  work_struct, 里面有个成员指针, 指向你最终要实现的函数。这是博客园Linux-workqueue讲解 - Vedic - 博客园 (cnblogs.com)

acpi_osi_init

该函数里面包含了acpi_install_interface_handler(acpi_osi_handler)和acpi_osi_setup_late()这两个函数。

acpi_install_interface_handler初始化acpi_gbl_interface_handler = acpi_osi_handler,acpi_install_interface_handler函数的作用是将指定的处理程序安装到 ACPI 接口,以便在 ACPI 事件发生时进行处理。

acpi_osi_setup_late如何通过字符串操作来灵活控制和报告给 BIOS 的操作系统接口信息。通过使用空字符串、以 ! 开头的字符串或普通字符串,开发人员可以禁用整个 _OSI,禁用某个特定接口,或者向接口列表中添加新的支持项。

static void __init acpi_osi_setup_late(void)
{
    struct acpi_osi_entry *osi;  // 定义指向 ACPI OSI 条目的指针
    char *str;                   // 定义指向字符串的指针,用于存储 OSI 字符串
    int i;                       // 循环计数器
    acpi_status status;          // 定义状态变量,用于存储返回状态

    // 检查是否需要禁用默认的 OSI 设置
    if (osi_config.default_disabling) {
        // 更新接口以禁用指定的 OSI 设置
        status = acpi_update_interfaces(osi_config.default_disabling);
        // 如果更新成功,打印相关信息
        if (ACPI_SUCCESS(status))
            pr_info("Disabled all _OSI OS vendors%s\n",
                osi_config.default_disabling ==
                ACPI_DISABLE_ALL_STRINGS ?
                " and feature groups" : "");
    }

    // 遍历所有定义的 OSI 字符串条目
    for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
        osi = &osi_setup_entries[i];  // 获取当前 OSI 条目,这是是个
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值