跳轉到內容

系統功能

來自華夏公益教科書


系統
使用者空間介面系統呼叫
驅動程式模型
模組
匯流排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 的電源管理
機會性掛起

構建和更新

[編輯 | 編輯原始碼]
更新
華夏公益教科書