內核必須懂(一): 用系統調用打印Hello, world!linux
內核必須懂(二): 文件系統初探shell
內核必須懂(三): 重編Ubuntu18.04LTS內核4.15.0vim
內核必須懂(四): 撰寫內核驅動bash
- 前言
- 虛擬機串口設置
- 測試串口
- 配置目標機
- 開始調試
- 調試驅動模塊
- 最後
調試內核確定不是什麼輕鬆的事情, 這裏是使用kgdb進行調試, 你理解的沒錯, 就是kernel版的gdb.測試
首先克隆下已經從新編譯內核的虛擬機 而後設置二者的串口, 這裏是用的win, mac端的串口我暫時還弄不太好, 因此很不情願地用了下win:ui
- 開發機
- 目標機
目標機執行:google
sudo cat /dev/ttyS1
複製代碼
開發機切換成root用戶, 執行:spa
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調試同樣了.
若是要寫驅動模塊, 必需要調試內核, 上述方法並非惟一方法. 下一篇將會介紹一些更實用的小工具來進行相似的調試. 喜歡記得點贊, 有意見或者建議評論區見哦~