背景
Read the fucking source code!
--By 鲁迅A picture is worth a thousand words.
--By 高尔基
说明:
- Kernel版本:4.14
- ARM64处理器
- 使用工具:Source Insight 3.5, Visio
1. 介绍
PSCI, Power State Coordination Interface
,由ARM定义的电源管理接口规范,通常由Firmware来实现,而Linux系统可以通过smc/hvc
指令来进入不同的Exception Level
,进而调用对应的实现。
那问题来了?为什么要把这个放到Firmware中去实现呢?原因是ARMv8架构,引入了Virtualization,Security等概念,CPU boot、shutdown、suspend/resumen等操作不再如传统那样单纯了。我们不再是我们,我们依然是我们。
2. 分析
代码路径:
arch/arm64/kernel/psci.c
drivers/firmware/psci.c
2.1 总体框架
Linux对CPU core的操作抽象出了结构struct cpu_operations
,开放给上层软件调用,struct cpu_operations
统一对底层的CPU及power等资源进行统一操作,完美。
今天我们的故事就从struct cpu_operations
开始。
话不多说,直接上图分析吧
CPU Operation
有两种方式:spin-table
和psci
,这个由Device Tree来指定,显然我们今天说的是psci
,以cpu_psci_ops
为核心;cpu_psci_ops
中的函数指针在arch/arm64/kernel/psci.c
中进行赋值,而实际的实现中去调用了psci_ops
中的实现;psci_ops
中会根据实际的Function ID找到对应的函数,从而通过hvc/smc
指令调用Firmware接口;
说一个实际的用例吧:
比如你现在需要把系统Suspend,在用户输入echo mem > /sys/power/state
,最终会调用到cpu_suspend
函数,由上图可知,最终也能调用到底层的Firmware,当然,前提是Firmware中已经实现了该接口。
所以,现在看起来PSCI其实就是去实现调用底层Firmware的接口,并且填充到对应的数据结构中就行了。
目前在内核中有三个版本的PSCI,分别是:PSCI V0.1/, PSCI V0.2/, PSCI V1.0
,对应的psci_of_match[]
一目了然:
static const struct of_device_id psci_of_match[] __initconst = {
{ .compatible = "arm,psci", .data = psci_0_1_init},
{ .compatible = "arm,psci-0.2", .data = psci_0_2_init},
{ .compatible = "arm,psci-1.0", .data = psci_0_2_init},
{},
};
2.1 PSCI v0.1分析
下边分析下PSCI v0.1吧
我们从哪里来?要到哪里去?老规矩,直接上图:
- 从
setup_arch
开始跟踪,能看到入口为psci_dt_init()
,从而跳转到driver/firmware/psci.c
中的函数中; psci_dt_init()
会去读取并解析Device Tree中的内容,从而选择版本(psci_0_1_init/psci_0_2_init),选择指令(hvc/smc)等;psci_0_1_init()
函数完成的主要内容其实是填充对应的函数指针,以及psci_function_id[]
数组;
那么如何从Device Tree到实际的解析和配置中来的呢?
下面以arch/arm/boot/dts/xenvm-4.2.dts
为例:
-
设备树是这样子的:
-
解析的框架是这样子的:
2.2 PSCI v0.2及以上与PSCI v0.1的区别
- 代码区别:PSCI v0.2支持 CPU Suspend,CPU Migrate等操作,也就是功能更全,显然我说的这个是废话,代码说明一切;
- DeviceTree的区别:
Case 1: PSCI v0.1 only.
psci {
compatible = "arm,psci";
method = "smc";
cpu_suspend = <0x95c10000>;
cpu_off = <0x95c10001>;
cpu_on = <0x95c10002>;
migrate = <0x95c10003>;
};
Case 2: PSCI v0.2 only
psci {
compatible = "arm,psci-0.2";
method = "smc";
};
Case 3: PSCI v0.2 and PSCI v0.1.
A DTB may provide IDs for use by kernels without PSCI 0.2 support,
enabling firmware and hypervisors to support existing and new kernels.
These IDs will be ignored by kernels with PSCI 0.2 support, which will
use the standard PSCI 0.2 IDs exclusively.
psci {
compatible = "arm,psci-0.2", "arm,psci";
method = "hvc";
cpu_on = < arbitrary value >;
cpu_off = < arbitrary value >;
...
};
说了是框架分析,不指望贴代码了,收工。
公众号: LoyenWang
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。