核心必須懂(一): 用系統呼叫列印Hello, world!
核心必須懂(三): 重編Ubuntu18.04LTS核心4.15.0
目錄
- 前言
- 虛擬機器串列埠設定
- 測試串列埠
- 配置目標機
- 開始除錯
- 除錯驅動模組
- 最後
前言
除錯核心肯定不是什麼輕鬆的事情, 這裡是使用kgdb進行除錯, 你理解的沒錯, 就是kernel版的gdb.
虛擬機器串列埠設定
首先克隆下已經重新編譯核心的虛擬機器 然後設定兩者的串列埠, 這裡是用的win, mac端的串列埠我暫時還弄不太好, 所以很不情願地用了下win:
- 開發機
- 目標機
測試串列埠
目標機執行:
sudo cat /dev/ttyS1
複製程式碼
開發機切換成root使用者, 執行:
echo “Hello, world!”>/dev/ttyS1
複製程式碼
配置目標機
開啟grub檔案:
sudo vim /etc/default/grub
複製程式碼
增加如下內容:
GRUB_CMDLINE_LINUX="nokaslr rootdelay=90quiet splash text kgdboc=ttyS1,115200“
複製程式碼
更新grub:
sudo update-grub
複製程式碼
nokaslr, 禁止核心地址隨機化, 具體內容請自行google:
reboot
複製程式碼
然後重啟的時候, 就能夠看到一行關於nokaslr的提示了.
開始除錯
然後開始測試一下kgdb的除錯, 目標機切換為root使用者, 控制許可權交給kgdb, 目標機進入假死狀態:
echo g > /proc/sysrq-trigger
複製程式碼
開發機進入自編譯核心目錄
gdb ./vmlinux
target remote /dev/ttyS1
handle SIGSEGV noprint nostop pass
break sys_clone
c
s
複製程式碼
這裡把斷點給到sys_clone, 就是大家熟悉的fork會呼叫的, 這樣基本等一會, 系統就自己呼叫, 然後進入除錯了. 之後就和使用gdb無異了:
除錯驅動模組
要除錯自己的寫的驅動模組, 就有些麻煩了, 首先需要常規的插入模組, 不多說了. 然後這裡有個shell指令碼可以獲取下一些所需引數, 主要是用來插入符號引數:
#!/bin/bash
#
# usage: gdbline.sh module_name module_path
#
# This script will outputs an add-symbol-file line suitable for pasting into gdb to examine
# a loaded module.
#
cd /sys/module/$1/sections
echo -n add-symbol-file $2 `/bin/cat .text`
for section in .[a-z]* *; do
if [ $section != ".text" ]; then
echo " \\"
echo -n " -s" $section `/bin/cat $section`
fi
done
echo
複製程式碼
首先, 需要在目標機make生成.ko檔案, 然後將這個.ko檔案拷貝至開發機的同名目錄下.
然後在目標機插入.ko檔案 用shell指令碼獲取.text, .data, .bss段基址. 如果你不太清楚這些東西, 還是請自行google, 因為如果展開, 篇幅就控制不住了.
目標機切換為root使用者, 控制許可權交給kgdb, 目標機進入假死狀態:
echo g > /proc/sysrq-trigger
複製程式碼
開發機進入自編譯核心目錄
gdb ./vmlinux
target remote /dev/ttyS1
handle SIGSEGV noprint nostop pass
複製程式碼
常規操作之前也說了, 然後就是新的操作, 要用add-symbol-file插入符號資訊, 然後輸入y確認:
然後把斷點打在模組函式DriverWrite中, 開始執行:
切回目標機, 已經不是假死了, 執行使用者態程式:
然後開發機就會觸發斷點:
接下來就和平常使用gdb除錯一樣了.
最後
如果要寫驅動模組, 必須要除錯核心, 上述方法並不是唯一方法. 下一篇將會介紹一些更實用的小工具來進行類似的除錯. 喜歡記得點贊, 有意見或者建議評論區見哦~