跳转到内容

系统功能

来自维基教科书,开放世界中的开放书籍


系统
用户空间接口系统调用
驱动程序模型
模块
总线PCI
硬件接口[重新]启动

本文介绍了用于支持和管理其他内核功能的基础设施。此功能以系统调用和 sysfs 命名。


用户空间通信是指用户空间应用程序和内核之间的数据和消息交换。用户空间应用程序是在操作系统用户空间中运行的程序,用户空间是内存中的一个受保护区域,它为应用程序提供安全且隔离的环境以在其内运行。

Linux 中有几种机制可用于用户空间与内核之间的通信。最常见的机制之一是通过系统调用,系统调用是允许用户空间应用程序请求内核服务的函数,例如打开文件、创建进程和访问系统资源。

用户空间通信的另一种机制是通过服务文件,服务文件是代表物理或虚拟设备的特殊文件,例如存储设备、网络接口和各种外围设备。用户空间应用程序可以通过读写它们相应的设备文件来与这些设备通信。

总之,Linux 内核提供了多种用户空间通信机制,包括系统调用、设备文件、procfssysfs 和 devtmpfs。这些机制使用户空间应用程序能够与内核通信并以安全且受控的方式访问系统资源。

⚲ API

用户空间的内核空间 API
uapiinc
arch/x86/include/uapisrc
man 2 ioctl
系统调用
设备文件
内核空间的用户空间 API
linux/uaccess.hinc:
copy_to_userid
copy_from_userid

📖 参考

用户空间 API 指南 doc
用户空间
Linux 内核接口
ULK3 第 11 章。信号


系统调用

[编辑 | 编辑源代码]

系统调用是用户空间应用程序与 Linux 内核之间的基本接口。它们提供了一种方法让程序请求操作系统的服务,例如打开文件、分配内存或创建新进程。在 Linux 内核中,系统调用是作为函数实现的,用户空间程序可以使用软件中断机制来调用这些函数。

Linux 内核提供了数百个系统调用,每个系统调用都有其独特的功能。这些系统调用被组织成类别,例如进程管理、文件管理、网络通信和内存管理。用户空间应用程序可以使用这些系统调用来与内核交互并访问底层系统资源。


⚲ API

系统调用表
man 2 syscalls


⚙️ 内部结构

linux/syscalls.hinc
syscall_init id 安装 entry_SYSCALL_64 id
man 2 syscall
entry_SYSCALL_64 id ↯ 调用层次结构
do_syscall_64id
sys_call_tableid


📖 参考

系统调用
系统调用目录,man 手册第 2 节
系统调用的剖析,第 1 部分第 2 部分
syscalls ltp


💾 历史

ULK3 第 10 章。系统调用

设备文件

[编辑 | 编辑源代码]

经典的 UNIX 设备是作为字节流使用man 2 ioctl字符设备

⚲ API

ls /dev
cat /proc/devices 
cat /proc/misc

示例:misc_fops id usb_fops id memory_fops id

分配的设备 doc
drivers/char src - 实际上是字节流设备
第 13 章。I/O 架构和设备驱动程序

⚠️ 警告:混淆。hiddev 不是真正的人机接口设备!它重新使用了 USBHID 基础设施。hiddev 例如用于监视器控制和不间断电源。此模块使用 /dev/usb/hiddevX 上的单独事件接口来单独支持这些设备(180:96 到 180:111)(⚙️ HIDDEV_MINOR_BASE id)

⚲ API

uapi/linux/hiddev.hinc
HID_CONNECT_HIDDEVid

⚙️ 内部结构

CONFIG_USB_HIDDEV
linux/hiddev.hinc
hiddev_eventid
drivers/hid/usbhid/hiddev.c srchiddev_fops id

📖 参考

HIDDEV - 人机接口设备的保养和维护 doc


📖 参考

设备文件

🔧 待办事项

📖 参考

man 7 netlink
Linux 内核用户和管理员指南 doc

proc 文件系统procfs)是一个特殊的 文件系统,它以层次文件结构的形式呈现有关进程和其他系统信息的信息,提供了一种比传统跟踪方法或直接访问内核内存更方便、更标准的方法来动态访问内核中保存的进程数据。通常,它在启动时映射到名为 /proc 的挂载点。proc 文件系统充当内核内部数据结构的接口。它可用于获取有关系统的信息,并在运行时更改某些内核参数。

/proc 包含一个目录,用于每个正在运行的进程(包括内核线程),这些目录命名为 /proc/PID,其中 PID 是进程号。每个目录都包含有关一个进程的信息,包括最初启动该进程的命令(/proc/PID/cmdline)、其环境变量的名称和值(/proc/PID/environ)、指向其工作目录的符号链接(/proc/PID/cwd)、指向原始可执行文件的另一个符号链接(如果仍然存在)(/proc/PID/exe)、两个包含指向每个打开的文件描述符的符号链接的目录(/proc/PID/fd)和每个文件描述符的状态(位置、标志等)(/proc/PID/fdinfo)、有关映射文件和块的信息(例如堆栈和堆)(/proc/PID/maps)、一个表示进程虚拟内存的二进制映像(/proc/PID/mem)、指向进程看到的根路径的符号链接(/proc/PID/root)、包含指向任何子进程或线程的硬链接的目录(/proc/PID/task)、有关进程的基本信息,包括其运行状态和内存使用情况(/proc/PID/status),以及更多信息。


📖 参考

procfs
man 5 procfs
man 7 命名空间
man 7 能力
linux/proc_fs.hinc
fs/procsrc

sysfs

[edit | edit source]

sysfs 是一个伪文件系统,它通过虚拟文件将有关内核子系统、硬件设备和相关设备驱动程序的信息从内核的设备模型导出到用户空间。除了提供有关各种设备和内核子系统的信息外,导出的虚拟文件还用于它们的配置。sysfs 旨在导出设备树中存在的信息,这样就不会再混乱 procfs。

sysfs 挂载在 /sys 挂载点下。

⚲ API

linux/sysfs.hinc

📖 参考

sysfs
man 5 sysfs
sysfs - 导出内核对象的文件系统 doc
fs/sysfssrc

devtmpfs

[edit | edit source]

devtmpfs 是一个内核/用户空间混合方法的设备文件系统,在 udev 首次运行之前提供节点。


📖 参考

设备文件
drivers/base/devtmpfs.csrc

容器化

[edit | edit source]

容器化 是一项强大的技术,它彻底改变了软件应用程序的开发、部署和运行方式。容器化的核心是为运行应用程序提供一个隔离的环境,应用程序在其中拥有所有必要的依赖关系,并且可以轻松地从一个环境移动到另一个环境,而无需担心任何兼容性问题。

容器化技术起源于 chroot 命令,该命令于 1979 年在 Unix 操作系统中引入。chroot 提供了一种更改进程根目录的方法,有效地创建了一个具有自己的文件系统层次结构的新隔离环境。但是,这种早期容器化实现的功能有限,难以管理和控制容器内运行的各种进程。

在 2000 年代初期,Linux 内核引入了 命名空间控制组,以提供更强大、更可扩展的容器化解决方案。命名空间 允许进程拥有自己的系统隔离视图,包括文件系统、网络和进程 ID 空间,而 控制组 则对分配给每个容器的资源(如 CPU、内存和 I/O)提供细粒度控制。

利用这些内核功能,容器化平台(如 DockerKubernetes)已成为大规模构建和部署容器化应用程序的流行解决方案。容器化已成为现代软件开发中必不可少的工具,使开发人员能够轻松地打包应用程序并在不同的环境中以一致且可预测的方式部署它们。

资源使用和限制

[edit | edit source]

⚲ API

man 2 chroot – 更改根目录
man 2 sysinfo – 返回系统信息
man 2 getrusage – 获取资源使用情况
获取/设置资源限制
man 2 getrlimit
man 2 setrlimit
man 2 prlimit64

📖 参考

chroot

命名空间

[edit | edit source]

Linux 命名空间 提供了一种隔离和虚拟化操作系统不同方面的方法。命名空间允许应用程序的多个实例在彼此隔离的情况下运行,而不会干扰主机系统或其他实例。

🔧 待办事项


⚲ API

/proc/self/ns
man 8 lsnsman 2 ioctl_nsns_ioctl id
man 1 unshareman 2 unshare
man 1 nsenterman 2 setns
man 2 clone3clone_args id
linux/ns_common.hinc
linux/proc_ns.hinc
命名空间定义
uts_namespaceid
ipc_namespaceid
mnt_namespaceid
pid_namespaceid
net/net_namespace.h inc - struct net
user_namespaceid
time_namespaceid
cgroup_namespaceid


⚙️ 内部结构

init_nsproxy id - 命名空间结构
kernel/nsproxy.csrc
fs/namespace.csrc
fs/proc/namespaces.csrc
net/core/net_namespace.csrc
kernel/time/namespace.csrc
kernel/user_namespace.csrc
kernel/pid_namespace.csrc
kernel/utsname.csrc
kernel/cgroup/namespace.csrc
ipc/namespace.csrc


📖 参考

man 7 命名空间
man 7 uts_namespaces
man 7 ipc_namespaces
man 7 mount_namespace
man 7 pid_namespaces
man 7 network_namespaces
man 7 user_namespaces
man 7 time_namespaces
man 7 cgroup_namespaces

控制组

[edit | edit source]

控制组 用于限制和控制进程组的资源使用。它们允许管理员设置对 CPU 使用率、内存使用率、磁盘 I/O、网络带宽和其他资源的限制,这对于管理系统性能和防止资源争用非常有用。

控制组有两个版本。与 v1 不同,控制组 v2 只有一个进程层次结构,它区分进程,而不是线程。


以下是控制组 v1 和 v2 之间的一些主要区别

控制组 v1 控制组 v2
层次结构 每个子系统都有自己的层次结构,这会导致复杂性和混乱 统一的层次结构,简化了管理,并实现了更好的资源分配
控制器 具有多个由独立控制器控制的子系统,每个子系统都有自己的配置文件和参数集 控制器被合并到单个 "cgroup2" 控制器中,该控制器提供了一个统一的接口来管理资源
资源分配 根据比例共享将资源分配给进程组,这会导致不可预测的结果 根据 "加权公平排队" 算法分配资源,这提供了更好的可预测性和公平性

控制组 v2 与控制组 v1 不兼容,这意味着从 v1 迁移到 v2 可能会很困难,并且需要仔细的规划。


🔧 待办事项


⚲ API

linux/cgroup.hinc
linux/cgroup-defs.hinc
css_set id – 持有指向 cgroup_subsys_state id 对象的引用计数指针集
cgroup_subsysid
linux/cgroup_subsys.h inc – 控制组子系统的列表


⚙️ 内部结构

cg_list id – task_struct 中 css_set id 的列表
kernel/cgroupsrc
cgroup_initid
cgroup2_fs_typeid


📖 参考

控制组 v1 文档
手册 1 systemd-cgtop
手册 5 systemd.slice – 切片单元配置
手册 7 cgroups
man 7 cgroup_namespaces
CFS 带宽控制用于控制组 文档
实时组调度 文档


📚 进一步阅读

https://github.com/containers

驱动程序模型

[编辑 | 编辑源代码]

Linux 驱动模型(或设备模型,或简称 DM)是一个框架,它为设备驱动程序提供了一种一致且标准化的方式来与内核交互。它定义了一套规则、接口和数据结构,使设备驱动程序能够与内核通信并执行各种操作,例如管理资源、生命周期等等。

DM 核心结构由 DM 类、DM 总线、DM 驱动程序和 DM 设备组成。


在 Linux 内核中,kobject id 是一个基本数据结构,用于表示内核对象并提供与它们交互的标准化接口。kobject 是一个通用对象,可以表示任何类型的内核对象,包括设备、文件、模块等等。

kobject 数据结构包含几个描述对象的字段,例如它的名称、类型、父级和操作。每个 kobject 在其父级对象中都有一个唯一的名称,而父子关系形成一个 kobject 的层次结构。

kobject 由内核的 sysfs 文件系统管理,该文件系统提供一个虚拟文件系统,将内核对象暴露为用户空间中的文件和目录。每个 kobject 都与一个 sysfs 目录相关联,该目录包含可以读取或写入以与内核对象交互的文件和属性。


⚲ 基础设施 API

linux/kobject.hinc
kobjectid
内核对象操作 文档
🔧 待办事项

类是设备的更高级别的视图,它抽象出低级别实现细节。驱动程序可能看到 NVME 存储或 SATA 存储,但在类级别,它们都只是 block_class id 设备。类允许用户空间基于设备的功能来处理设备,而不是它们连接的方式或工作方式。通用 DM 类结构与 组合模式 匹配。

⚲ API

ls /sys/class/
class_register id 注册 class id
linux/device/class.hinc

👁 例子:input_class idblock_class id net_class id


一个 外设总线 是处理器和一个或多个外设之间的一个通道。DM 总线是 代理 用于外设总线。通用 DM 总线结构与 组合模式 匹配。就设备模型而言,所有设备都通过总线连接,即使它是内部的、虚拟的,platform_bus_type id。总线可以互相连接。例如,USB 控制器通常是 PCI 设备。设备模型表示总线之间以及它们控制的设备之间的实际连接。总线由 bus_type id 结构表示。它包含名称、默认属性、总线的方法、PM 操作以及驱动程序内核的私有数据。


⚲ API

ls /sys/bus/
bus_register id 注册 bus_type id
linux/device/bus.hinc


👁 例子:usb_bus_type idhid_bus_type idpci_bus_type idscsi_bus_type idplatform_bus_type id

外设总线


驱动程序

[编辑 | 编辑源代码]

⚲ API

ls /sys/bus/:/drivers/
module_driver id - 简单的通用驱动程序初始化程序,👁 例如在 module_pci_driver id 中使用
driver_register id 注册 device_driver id - 基本的设备驱动程序结构,每个设备实例一个。
linux/device/driver.hinc

👁 例子:hid_generic id usb_register_device_driver id


平台驱动程序

module_platform_driver id 注册 platform_driver iddevice_driver id 的平台包装器)和 platform_bus_type id
linux/platform_device.hinc

👁 例子:gpio_mouse_device_driver id


⚲ API

ls /sys/devices/
device_register id 注册 device id - 基本的设备结构,每个设备实例一个
linux/device.hinc
linux/dev_printk.hinc
设备资源管理 文档,devres,devm ...

👁 例子:platform_bus id mousedev_create


平台设备

platform_device id - struct device - 基本的设备结构 文档 的平台包装器,包含与设备相关的资源
它可以由 platform_device_register_simple idplatform_device_alloc id 动态自动创建。或者使用 platform_device_register id 注册。
platform_device_unregister id - 释放设备和相关资源

👁 例子:add_pcspkr id


⚲ API 🔧 待办事项

platform_device_info platform_device_id platform_device_register_full platform_device_add
platform_device_add_data platform_device_register_data platform_device_add_resources
attribute_group dev_pm_ops



⚙️ 内部结构

linux/dev_printk.hinc
lib/kobject.csrc
drivers/base/platform.csrc
drivers/base/core.csrc

📖 参考

设备驱动程序基础设施 文档
关于 kobject、kset 和 ktype 的一切你不愿知道的事 文档
驱动模型 文档
Linux 内核设备模型 文档
平台设备和驱动程序 文档
Linux 设备模型,由 linux-kernel-labs 提供
关于模块的文章


⚲ API

lsmod
cat /proc/modules


⚙️ 内部结构

kernel/kmod.csrc


📖 参考

LDD3:构建和运行模块
http://www.xml.com/ldd/chapter/book/ch02.html
http://www.tldp.org/LDP/tlk/modules/modules.html
http://www.tldp.org/LDP/lkmpg/2.6/html/ Linux 内核模块编程指南

外设总线是用于将各种外围设备连接到计算机系统的通信通道。这些总线用于在外围设备和系统的处理器或内存之间传输数据。在 Linux 内核中,外设总线作为驱动程序实现,这些驱动程序使操作系统与硬件之间的通信成为可能。

Linux 内核中的外设总线包括 USB、PCI、SPI、I2C 等等。这些总线中的每一个都有其自身独特的特性,并且 Linux 内核为各种外设提供了支持。

PCI(外设组件互连)总线用于连接计算机系统中的内部硬件设备。它通常用于连接显卡、网卡和其他扩展卡。Linux 内核提供了 PCI 总线驱动程序,使操作系统与连接到总线的设备之间的通信成为可能。

USB(通用串行总线)是现代计算机系统中最常用的外设总线之一。它允许设备进行热插拔,并支持高速数据传输速率。


🔧 待办:设备枚举


⚲ API

Shell 接口:ls /proc/bus/ /sys/bus/

另请参见 驱动模型的总线

参见 输入:键盘、鼠标等

PCI

⚲ Shell API

lspci -vv
column -t /proc/bus/pci/devices

主条目:PCI


USB

⚲ Shell API

lsusb -v
ls /sys/bus/usb/
cat /proc/bus/usb/devices


⚙️ 内部结构

drivers/usbsrc


📖 参考

USB 文档
LDD3:USB 驱动程序


其他总线

drivers/bussrc


🤖 嵌入式设备的总线

linux/gpio/driver.h 包含 linux/gpio.h 包含 drivers/gpio 源码 tools/gpio 源码
drivers/i2c 源码 https://i2c.wiki.kernel.org


SPI

⚲ API

linux/spi/spi.hinc
tools/spisrc

⚙️ 内部结构

drivers/spisrc
spi_register_controllerid
spi_controller_list 标识符🚧

📖 参考

SPI 文档

硬件接口

[编辑 | 编辑源代码]

硬件接口是任何操作系统的基本组成部分,它使处理器与计算机系统的其他硬件组件(内存、外设和总线、各种控制器)之间的通信成为可能。

中断

I/O 端口和寄存器

[编辑 | 编辑源代码]

I/O 端口和寄存器是计算机系统中的电子组件,它们使 CPU 与其他电子控制器和设备之间的通信成为可能。

⚲ API

linux/regmap.h 包含 — 寄存器映射访问 API

asm-generic/io.h 包含 — 通用 I/O 端口模拟。

ioport_mapid
ioread32 标识符 / iowrite32 标识符 ...
readl 标识符/ writel 标识符 ...
宏 {in,out}[bwl] 用于模拟 x86 风格的 PCI/ISA IO 空间
inl 标识符/ outl 标识符 ...

linux/ioport.h 包含 — 定义用于检测、保留和分配系统资源的例程。

request_mem_regionid


arch/x86/include/asm/io.hsrc

内存映射寄存器的函数

ioremapid ...

硬件设备驱动程序

[编辑 | 编辑源代码]

关键字:固件、热插拔、时钟、复用器、引脚

⚙️ 内部结构

drivers/acpisrc
drivers/basesrc
drivers/sdio 源码 - 安全数字输入输出
drivers/virtiosrc
drivers/hwmonsrc
drivers/thermalsrc
drivers/pinctrlsrc
drivers/clksrc


📖 参考

引脚控制子系统 文档
Linux 硬件监控 文档
固件指南 文档
设备树 文档
https://hwmon.wiki.kernel.org/
LDD3:Linux 设备模型
http://www.tldp.org/LDP/tlk/dd/drivers.html
http://www.xml.com/ldd/chapter/book/
http://examples.oreilly.com/linuxdrive2/

引导和停止

[编辑 | 编辑源代码]

内核引导

[编辑 | 编辑源代码]

内核是在两个阶段加载的 - 在第一个阶段,内核(作为压缩的镜像文件)被加载到内存并解压缩,并且设置了一些基本功能,例如基本硬件和基本内存管理(内存分页)。然后,控制最终切换到调用start_kernel 标识符的主内核启动过程,然后在生成单独的空闲进程和调度器以及 init 进程(在用户空间执行)之前执行大部分系统设置(中断、内存管理的其余部分、设备和驱动程序初始化等)。

内核加载阶段

加载的内核通常是镜像文件,使用 zlib 压缩为 zImage 或 bzImage 格式。它头部的例程执行最少的硬件设置,将镜像完全解压缩到高内存,并注意是否配置了任何 RAM 磁盘。然后,它通过 startup_64(对于 x86_64 架构)执行内核启动。

arch/x86/boot/compressed/vmlinux.lds.S 源码 - 链接器脚本定义了入口点 startup_64 标识符
arch/x86/boot/compressed/head_64.S 源码 - 提取器的汇编
extract_kernel 标识符 - C 语言中的提取器
打印
Decompressing Linux... done.
Booting the kernel.

内核启动阶段

内核的启动函数(也称为交换器或进程 0)建立内存管理(分页表和内存分页),检测 CPU 类型和任何附加功能(例如浮点功能),然后通过调用 start_kernel 标识符切换到非架构特定的 Linux 内核功能。


↯ 启动调用层次结构

arch/x86/kernel/vmlinux.lds.S src – 链接器脚本
arch/x86/kernel/head_64.S src – 未压缩启动代码的汇编
arch/x86/kernel/head64.c src – 平台相关的启动
x86_64_start_kernelid
x86_64_start_reservationsid
init/main.c src – 主要初始化代码
start_kernel id 200 SLOC
mm_initid
mem_initid
vmalloc_initid
sched_initid
rcu_init id读-复制-更新
rest_initid
kernel_init id - 延迟内核线程 #1
kernel_init_freeable id 此函数和以下函数都使用属性 __init id 定义
prepare_namespaceid
initrd_loadid
mount_rootid
run_init_process id 显然会运行第一个进程 man 1 init
kthreadd id – 延迟内核线程 #2
cpu_startup_entryid
do_idleid

start_kernel id 执行了大量初始化函数。它设置了中断处理(IRQs),进一步配置内存,启动了 man 1 init 进程(第一个用户空间进程),然后通过 cpu_startup_entry id 启动了空闲任务。值得注意的是,内核启动过程还会挂载之前加载的 初始 RAM 磁盘(initrd),作为启动阶段的临时根文件系统。initrd 允许驱动程序模块直接从内存加载,而无需依赖其他设备(例如硬盘)及其访问所需驱动程序(例如 SATA 驱动程序)。这种将部分驱动程序静态编译到内核中而将其他驱动程序从 initrd 加载的方式可以缩减内核体积。稍后通过调用 man 8 pivot_root / man 2 pivot_root 来切换根文件系统,该调用会卸载临时根文件系统并将其替换为真正的根文件系统,前提是真正的根文件系统已可访问。然后,临时根文件系统所使用的内存会被回收。


⚙️ 内部结构

arch/x86/Kconfig.debugsrc
linux/smpboot.hinc
kernel/smpboot.csrc
arch/x86/kernel/smpboot.csrc

📖 参考

关于 内核启动 的文章
初始 RAM 磁盘 doc
Linux 启动过程
init
Linux (U)EFI 启动过程
内核的命令行参数 doc
启动配置 doc
启动时内存管理 doc
内核启动过程
内核初始化过程


📚 进一步阅读

启动时跟踪 doc


💾 历史

http://tldp.org/HOWTO/Linux-i386-Boot-Code-HOWTO/
http://www.tldp.org/LDP/lki/lki-1.html
http://www.tldp.org/HOWTO/KernelAnalysis-HOWTO-4.html

挂起或重启

[edit | edit source]

🔧 待办事项


⚲ API

linux/reboot.hinc
linux/stop_machine.hinc
reboot_modeid
sys_reboot id 调用
machine_restart id 或者
machine_halt id 或者
machine_power_offid
linux/reboot-mode.hinc
reboot_mode_driverid
devm_reboot_mode_registerid


⚙️ 内部结构

kernel/reboot.csrc
kernel/stop_machine.csrc
arch/x86/kernel/reboot.csrc
Softdog 驱动程序

电源管理

[edit | edit source]

关键字:挂起、警报、休眠。


⚲ API

/sys/power/
/sys/kernel/debug/wakeup_sources
⌨️动手操作
sudo awk '{gsub("^ ","?")} NR>1 {if ($6) {print $1}}' /sys/kernel/debug/wakeup_sources
linux/pm.hinc
linuxinc
linux/pm_qos.hinc
linux/pm_clock.hinc
linux/pm_domain.hinc
linux/pm_wakeirq.hinc
linux/pm_wakeup.hinc
wakeup_sourceid
wakeup_source_registerid
linux/suspend.hinc
pm_suspend id 挂起系统
挂起和唤醒依赖于
man 2 timer_createman 2 timerfd_create,如果使用时钟 ID CLOCK_REALTIME_ALARM idCLOCK_BOOTTIME_ALARM id,系统在挂起时会被唤醒。
man 2 epoll_ctl 使用标志 EPOLLWAKEUP id 会阻止挂起
另请参阅 man 7 capabilities CAP_WAKE_ALARM idCAP_BLOCK_SUSPEND id


⚙️ 内部结构

CONFIG_PMid
CONFIG_SUSPENDid
kernel/powersrc
alarm_initid
kernel/time/alarmtimer.csrc
drivers/base/power src: wakeup_sources id


📖 参考

PM 管理 doc
CPU 和设备 PM doc
电源管理 doc
sysfs 电源测试 ABI doc
https://lwn.net/Kernel/Index/#Power_management
PowerTOP
cpupower
tlp – 应用笔记本电脑电源管理设置
ACPI – 高级配置和电源接口
运行时 PM
[edit | edit source]

关键字:运行时电源管理、设备电源管理、机会性挂起、自动挂起、自动休眠。


⚲ API

/sys/devices/.../power/
async autosuspend_delay_ms control runtime_active_kids runtime_active_time runtime_enabled runtime_status runtime_suspended_time runtime_usage
linux/pm_runtime.hinc
pm_runtime_mark_last_busyid
pm_runtime_enableid
pm_runtime_disableid
pm_runtime_get id – 异步获取
pm_runtime_get_syncid
pm_runtime_resume_and_get id – 优先使用同步获取
pm_runtime_putid
pm_runtime_put_noidle id – 只减计数器
pm_runtime_put_syncid
pm_runtime_put_autosuspendid
SET_RUNTIME_PM_OPSid


👁 例子:ac97_pm id


⚙️ 内部结构

CONFIG_PM_AUTOSLEEPid


📖 参考

I/O 设备的运行时电源管理框架 doc
实时工作负载的 CPU 空闲节能方法
Sysfs 设备 PM API
USB 的电源管理
机会性挂起

构建和更新

[编辑 | 编辑源代码]
更新
华夏公益教科书