1 內核調試以及工具總結
內核總是那么捉摸不透, 內核也會犯錯, 但是調試卻不能像用戶空間程序那樣, 為此內核開發者為我們提供了一系列的工具和系統來支持內核的調試.
內核的調試, 其本質是內核空間與用戶空間的數據交換, 內核開發者們提供了多樣的形式來完成這一功能.
2 用戶空間與內核空間數據交換的文件系統
內核中有三個常用的偽文件系統: procfs, debugfs和sysfs.
它們都用于Linux內核和用戶空間的數據交換, 但是適用的場景有所差異:
procfs
歷史最早, 最初就是用來跟內核交互的唯一方式, 用來獲取處理器、內存、設備驅動、進程等各種信息.sysfs
跟kobject
框架緊密聯系, 而kobject
是為設備驅動模型而存在的, 所以sysfs
是為設備驅動服務的.debugfs
從名字來看就是為debug
而生, 所以更加靈活.relayfs
是一個快速的轉發(relay)
數據的文件系統, 它以其功能而得名. 它為那些需要從內核空間轉發大量數據到用戶空間的工具和應用提供了快速有效的轉發機制.
相關資料鏈接:
在 Linux 下用戶空間與內核空間數據交換的方式, 第 2 部分: procfs、seq_file、debugfs和relayfs:http://www.ibm.com/developerworks/cn/linux/l-kerns-usrs2/
Linux 文件系統:procfs, sysfs, debugfs 用法簡介:http://www.tinylab.org/show-the-usage-of-procfs-sysfs-debugfs/
2.1 procfs文件系統
ProcFs
介紹
procfs
是比較老的一種用戶態與內核態的數據交換方式, 內核的很多數據都是通過這種方式出口給用戶的, 內核的很多參數也是通過這種方式來讓用戶方便設置的. 除了 sysctl
出口到 /proc
下的參數, procfs
提供的大部分內核參數是只讀的. 實際上, 很多應用嚴重地依賴于procfs, 因此它幾乎是必不可少的組件. 前面部分的幾個例子實際上已經使用它來出口內核數據, 但是并沒有講解如何使用, 本節將講解如何使用procfs
.
-
參考資料:
用戶空間與內核空間數據交換的方式(2)——procfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011141.html
2.2 sysfs文件系統
內核子系統或設備驅動可以直接編譯到內核, 也可以編譯成模塊, 編譯到內核, 使用前一節介紹的方法通過內核啟動參數來向它們傳遞參數, 如果編譯成模塊, 則可以通過命令行在插入模塊時傳遞參數, 或者在運行時, 通過 sysfs
來設置或讀取模塊數據.
Sysfs
是一個基于內存的文件系統, 實際上它基于ramfs
, sysfs
提供了一種把內核數據結構, 它們的屬性以及屬性與數據結構的聯系開放給用戶態的方式, 它與 kobject
子系統緊密地結合在一起, 因此內核開發者不需要直接使用它, 而是內核的各個子系統使用它. 用戶要想使用 sysfs
讀取和設置內核參數, 僅需裝載 sysfs
就可以通過文件操作應用來讀取和設置內核通過 sysfs
開放給用戶的各個參數:
mkdir -p /sysfs
mount -t sysfs sysfs /sysfs
注意, 不要把 sysfs
和 sysctl
混淆, sysctl
是內核的一些控制參數, 其目的是方便用戶對內核的行為進行控制, 而 sysfs
僅僅是把內核的 kobject
對象的層次關系與屬性開放給用戶查看, 因此 sysfs
的絕大部分是只讀的, 模塊作為一個 kobject
也被出口到 sysfs
, 模塊參數則是作為模塊屬性出口的, 內核實現者為模塊的使用提供了更靈活的方式, 允許用戶設置模塊參數在 sysfs
的可見性并允許用戶在編寫模塊時設置這些參數在 sysfs
下的訪問權限, 然后用戶就可以通過 sysfs
來查看和設置模塊參數, 從而使得用戶能在模塊運行時控制模塊行為.
相關資料鏈接:
用戶空間與內核空間數據交換的方式(6)——模塊參數與sysfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011470.html
2.3 debugfs文件系統
內核開發者經常需要向用戶空間應用輸出一些調試信息, 在穩定的系統中可能根本不需要這些調試信息, 但是在開發過程中, 為了搞清楚內核的行為, 調試信息非常必要, printk可能是用的最多的, 但它并不是最好的, 調試信息只是在開發中用于調試, 而 printk
將一直輸出, 因此開發完畢后需要清除不必要的 printk
語句, 另外如果開發者希望用戶空間應用能夠改變內核行為時, printk
就無法實現.
因此, 需要一種新的機制, 那只有在需要的時候使用, 它在需要時通過在一個虛擬文件系統中創建一個或多個文件來向用戶空間應用提供調試信息.
有幾種方式可以實現上述要求:
- 使用
procfs
, 在/proc
創建文件輸出調試信息, 但是procfs
對于大于一個內存頁(對于x86
是4K
)的輸出比較麻煩, 而且速度慢, 有時回出現一些意想不到的問題. - 使用
sysfs
(2.6
內核引入的新的虛擬文件系統), 在很多情況下, 調試信息可以存放在那里, 但是sysfs主要用于系統管理,它希望每一個文件對應內核的一個變量,如果使用它輸出復雜的數據結構或調試信息是非常困難的. - 使用
libfs
創建一個新的文件系統, 該方法極其靈活, 開發者可以為新文件系統設置一些規則, 使用libfs
使得創建新文件系統更加簡單, 但是仍然超出了一個開發者的想象.
為了使得開發者更加容易使用這樣的機制, Greg Kroah-Hartman
開發了 debugfs
(在 2.6.11
中第一次引入), 它是一個虛擬文件系統, 專門用于輸出調試信息, 該文件系統非常小, 很容易使用, 可以在配置內核時選擇是否構件到內核中, 在不選擇它的情況下, 使用它提供的API的內核部分不需要做任何改動.
相關資料鏈接:
用戶空間與內核空間數據交換的方式(1)——debugfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011124.html
Linux內核里的DebugFS:http://www.cnblogs.com/wwang/archive/2011/01/17/1937609.html
Linux驅動調試的Debugfs的使用簡介:http://soft.chinabyte.com/os/110/12377610.shtml
Linux Debugfs文件系統介紹及使用:http://blog.sina.com.cn/s/blog_40d2f1c80100p7u2.html
Linux內核里的DebugFS:http://www.cnblogs.com/wwang/archive/2011/01/17/1937609.html
Debugging the Linux Kernel with debugfs:http://opensourceforu.com/2010/10/debugging-linux-kernel-with-debugfs/
debugfs-seq_file:http://lxr.free-electrons.com/source/drivers/base/power/wakeup.c
Linux Debugfs文件系統介紹及使用:http://blog.sina.com.cn/s/blog_40d2f1c80100p7u2.html
Linux 文件系統:procfs, sysfs, debugfs 用法簡介:http://www.tinylab.org/show-the-usage-of-procfs-sysfs-debugfs/
用戶空間與內核空間數據交換的方式(1)——debugfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011124.html
Linux 運用debugfs調試方法:http://www.xuebuyuan.com/1023006.html
2.4 relayfs文件系統
relayfs
是一個快速的轉發(relay
)數據的文件系統, 它以其功能而得名. 它為那些需要從內核空間轉發大量數據到用戶空間的工具和應用提供了快速有效的轉發機制.
Channel
是 relayfs
文件系統定義的一個主要概念, 每一個 channel
由一組內核緩存組成, 每一個 CPU
有一個對應于該 channel
的內核緩存, 每一個內核緩存用一個在 relayfs
文件系統中的文件文件表示, 內核使用 relayfs
提供的寫函數把需要轉發給用戶空間的數據快速地寫入當前 CPU
上的 channel
內核緩存, 用戶空間應用通過標準的文件 I/
O函數在對應的 channel
文件中可以快速地取得這些被轉發出的數據 mmap
來. 寫入到 channel
中的數據的格式完全取決于內核中創建channel
的模塊或子系統.
relayfs
的用戶空間API
:
relayfs
實現了四個標準的文件 I/O
函數, open、mmap、poll和close
注意 : 用戶態應用在使用上述 API 時必須保證已經掛載了 relayfs 文件系統, 但內核在創建和使用 channel時不需要relayfs 已經掛載. 下面命令將把 relayfs 文件系統掛載到 /mnt/relay.
相關資料鏈接:
用戶空間與內核空間數據交換的方式(4)——relayfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011270.html
Relay:一種內核到用戶空間的高效數據傳輸技術:https://www.ibm.com/developerworks/cn/linux/l-cn-relay/
2.5 seq_file
一般地, 內核通過在 procfs
文件系統下建立文件來向用戶空間提供輸出信息, 用戶空間可以通過任何文本閱讀應用查看該文件信息, 但是 procfs
有一個缺陷, 如果輸出內容大于1個內存頁, 需要多次讀,因此處理起來很難, 另外, 如果輸出太大, 速度比較慢, 有時會出現一些意想不到的情況, Alexander Viro
實現了一套新的功能, 使得內核輸出大文件信息更容易, 該功能出現在 2.4.15
(包括 2.4.15
)以后的所有 2.4
內核以及 2.6
內核中, 尤其是在 2.6
內核中,已經大量地使用了該功能
相關資料鏈接:
用戶空間與內核空間數據交換的方式(3)——seq_file:http://www.cnblogs.com/hoys/archive/2011/04/10/2011261.html
內核proc文件系統與seq接口(4)—seq_file接口編程淺析:http://blog.chinaunix.net/uid-20543672-id-3235254.html
Linux內核中的seq操作:http://www.cnblogs.com/qq78292959/archive/2012/06/13/2547335.html
seq_file源碼分析:http://www.cppblog.com/csjiaxin/articles/136681.html
用序列文件(seq_file)接口導出常用數據結構:http://blog.chinaunix.net/uid-317451-id-92670.html
seq_file機制:http://blog.csdn.net/a8039974/article/details/24052619
3 printk
在內核調試技術之中, 最簡單的就是 printk
的使用了, 它的用法和C語言應用程序中的 printf
使用類似, 在應用程序中依靠的是 stdio.h
中的庫, 而在 linux
內核中沒有這個庫, 所以在 linux
內核中,實現了自己的一套庫函數, printk
就是標準的輸出函數
相關資料鏈接:
linux內核調試技術之printk:http://www.cnblogs.com/veryStrong/p/6218383.html
調整內核printk的打印級別:http://blog.csdn.net/tonywgx/article/details/17504001
linux設備驅動學習筆記–內核調試方法之printk:http://blog.csdn.net/itsenlin/article/details/43205983
4 ftrace && trace-cmd
4.1 trace && ftrace
Linux
當前版本中, 功能最強大的調試、跟蹤手段. 其最基本的功能是提供了動態和靜態探測點, 用于探測內核中指定位置上的相關信息.
靜態探測點, 是在內核代碼中調用 ftrace
提供的相應接口實現, 稱之為靜態是因為, 是在內核代碼中寫死的, 靜態編譯到內核代碼中的, 在內核編譯后, 就不能再動態修改. 在開啟 ftrace
相關的內核配置選項后, 內核中已經在一些關鍵的地方設置了靜態探測點, 需要使用時, 即可查看到相應的信息.
動態探測點, 基本原理為 : 利用 mcount
機制, 在內核編譯時, 在每個函數入口保留數個字節, 然后在使用 ftrace
時, 將保留的字節替換為需要的指令, 比如跳轉到需要的執行探測操作的代碼。
ftrace
的作用是幫助開發人員了解 Linux
內核的運行時行為, 以便進行故障調試或性能分析.
最早 ftrace
是一個 function tracer
, 僅能夠記錄內核的函數調用流程. 如今 ftrace
已經成為一個
framework
, 采用 plugin
的方式支持開發人員添加更多種類的 trace
功能.
Ftrace
由 RedHat
的 Steve Rostedt
負責維護. 到 2.6.30
為止, 已經支持的 tracer
包括 :
這里還沒有列出所有的 tracer
, ftrace
是目前非常活躍的開發領域, 新的 tracer
將不斷被加入內核。
相關資料鏈接:
ftrace和它的前端工具trace-cmd(深入了解Linux系統的利器):http://blog.yufeng.info/archives/1012
ftrace 簡介:https://www.ibm.com/developerworks/cn/linux/l-cn-ftrace/
內核性能調試–ftrace:http://blog.chinaunix.net/uid-20589411-id-3501525.html
使用 ftrace 調試 Linux 內核,第 1 部分:https://www.ibm.com/developerworks/cn/linux/l-cn-ftrace1
ftrace的使用:http://blog.csdn.net/cybertan/article/details/8258394
[轉]Linux內核跟蹤之trace框架分析:http://blog.chinaunix.net/uid-24063584-id-2642103.html
Linux trace使用入門:http://blog.csdn.net/jscese/article/details/46415531
4.2 ftrace前端工具trace-cmd
- trace-cmd 介紹
trace-cmd
和 開源的 kernelshark
均是內核Ftrace
的前段工具, 用于分分析核性能.
他們相當于是一個 /sys/kernel/debug/tracing
中文件系統接口的封裝, 為用戶提供了更加直接和方便的操作.
- 使用
# 收集信息
sudo trace-cmd reord subsystem:tracing
# 解析結果
#sudo trace-cmd report
trace-cmd: A front-end for Ftrace:https://lwn.net/Articles/410200/
其本質就是對/sys/kernel/debug/tracing/events
下各個模塊進行操作, 收集數據并解析
-
內核
+關注
關注
3文章
1405瀏覽量
40994 -
數據
+關注
關注
8文章
7233瀏覽量
90834 -
Linux
+關注
關注
87文章
11432瀏覽量
212457 -
開發
+關注
關注
0文章
372瀏覽量
41275
發布評論請先 登錄
Linux內核開發工具介紹

Linux內核鏡像bzImage和rootfs的制作、安裝及調試過程

評論