天天看點

樹莓派4B進階11-基于arm32 raspberry開啟kdump(1)

作者:菜卓001

平常工作主要涉及系統性能穩定性的工作,而kernel panic問題也是經常會遇到的,掌握panic的調試技巧,對于分析定位核心崩潰的問題,有着非常重要的作用。本文不涉及kdump原理,主要介紹基于yocto建構環境在arm開發闆上開啟kdump功能,并抓取vmcore。

環境

  • ubuntu 22.04
  • raspiberry 4B
  • U盤 64G
  • yocto 4.1.2
  • vmware 16.2.4
  • kernel 5.15.56
  • kexec-tools 2.0.25

yocto安裝kexec

yocto環境搭建可以參考前面的系列文章,強烈推薦使用yocto來定制系統。

yocto預設帶有kexec的recipe的,可以通過指令查詢确認:

$ bitbake -s |grep kexec
kexec-tools                                        :2.0.25-r0             

在conf/local.conf中添加kexec工具:

IMAGE_INSTALL:append = " kexec-tools"           

注:老版本使用的是IMAGE_INSTALL_append,新版本文法采用":",并且kexec-tools前面有個空格。

yocto安裝makedumpfile

yocto預設不帶有makedumpfile的recipe,需要借助meta-openembedded。meta-openembedded 是filesystems、initramfs、multimedia、networking meta-oe 等layer的集合,包含了很多有用的recipes。

  1. 下載下傳openembedded
cd xxx/yocto/poky
git clone https://github.com/openembedded/meta-openembedded.git -b langdale  #我這裡使用的是langdale分支           
  1. makedumpfile的recipe包含在meta-oe layer中,需要把meta-oe添加到conf/bblayers.conf配置檔案中:
...
BBLAYERS ?= " \
   ...
  /home/lxq/Desktop/workspace/02.yocto/poky/meta-raspberrypi \
  /home/lxq/Desktop/workspace/02.yocto/poky/meta-mylayer \
  /home/lxq/Desktop/workspace/02.yocto/poky/meta-openembedded/meta-oe \  #新增
  "           

确認是否配置生效:

$ bitbake -s |grep makedump
makedumpfile                                        :1.7.2-r0              

kernel開啟kdump

kdump功能需要設定以下宏:

CONFIG_KEXEC=y
CONFIG_DEBUG_INFO=y
CONFIG_CRASH_DUMP=y
CONFIG_SYSFS=y
CONFIG_PROC_VMCORE=y
CONFIG_SMP=n            

注:需要關閉SMP,否則會報kexec_load failed: Invalid argument。

通過如下指令:

$ bitbake linux-raspberrypi -c menuconfig
$ bitbake linux-raspberrypi           

crashkernel參數設定

通過設定crashkernel參數預留給dump-capture kernel部分記憶體,避免記憶體不足時無法啟動。

crashkernel=Y@X           

Y表示預留大小;X表示預留記憶體起始位址。如128M@32M:預留記憶體大小為128M,實體起始位址為0x01000000 (16MB)。而arm架構X不是必須的,不提供情況下會在RAM第一個512M自動定位起始位址.

官方解釋:On arm, the use of "crashkernel=Y@X" is no longer necessary; the kernel will automatically locate the crash kernel image within the first 512MB of RAM if X is not given.

我這裡是在rpi-cmdline.bb進行追加crashkernel:

CMDLINE_ROOTFS = "root=/dev/sda2 ${CMDLINE_ROOT_FSTYPE} rootwait crashkernel=128M"           
樹莓派4B進階11-基于arm32 raspberry開啟kdump(1)

增大rootfs磁盤空間

當panic發生時生成vmcore,該檔案比較大,本人測試環境生成的在4G左右,而鏡像中的rootfs隻有2.4G,儲存vmcore檔案時提示磁盤空間不足,是以需要定制image時增大rootfs磁盤空間。

在conf/local.conf中設定IMAGE_ROOTFS_EXTRA_SPACE參數,我這裡增加了5G:

IMAGE_ROOTFS_EXTRA_SPACE = "5242880"           

到這裡已經完成了前期準備,重新編譯image燒錄驗證。

手動驗證kdump

确認crashkernel和kdump是否設定成功。

  1. 檢視預留大小,我這裡設定的是128M:
root@raspberrypi4:~# cat /sys/kernel/kexec_crash_size
134217728           
  1. 手動加載dump-capture kernel到預留的記憶體中,當觸發panic時會從第一個kernel進入到dump-capture kernel運作。通過檢視kexec_crash_loaded确認是否加載成功,0:未加載,1:已加載,
root@raspberrypi4:~# cat /sys/kernel/kexec_crash_loaded
0
root@raspberrypi4:~# kexec --type zImage -p /boot/zImage-5.15.56-v7l --append="'cat /proc/cmdline'"
root@raspberrypi4:~# cat /sys/kernel/kexec_crash_loaded
1           
  1. 手動觸發panic
echo c > /proc/sysrq-trigger           

通過序列槽觀察輸出确認功能是否正常:

[  113.992841]  r5:c08187f4 r4:c2003d80
[  113.996465] [<c04cfc6c>] (proc_reg_write) from [<c042f240>] (vfs_write+0xec/0x464)
[  114.004163]  r10:00000004 r9:c2237800 r8:c2e97f68 r7:0213fc78 r6:c04cfc6c r5:00000002
[  114.012107]  r4:c23e03c0 r3:c2e97f68
[  114.015732] [<c042f154>] (vfs_write) from [<c042f758>] (ksys_write+0x80/0x104)
[  114.023074]  r9:c2e96000 r8:c0200264 r7:00000000 r6:00000000 r5:c23e03c0 r4:c23e03c0
[  114.030929] [<c042f6d8>] (ksys_write) from [<c042f7f4>] (sys_write+0x18/0x1c)
[  114.038181]  r7:00000004 r6:00000001 r5:0213fc78 r4:00000002
[  114.043920] [<c042f7dc>] (sys_write) from [<c0200060>] (ret_fast_syscall+0x0/0x1c)
[  114.051611] Exception stack(0xc2e97fa8 to 0xc2e97ff0)
[  114.056741] 7fa0:                   00000002 0213fc78 00000001 0213fc78 00000002 00000001
[  114.065043] 7fc0: 00000002 0213fc78 00000001 00000004 005305bc 00000020 be81a638 0213d404
[  114.073341] 7fe0: 00000004 be81a5f0 b6eaf3a3 b6e2e576
[  114.078493] Loading crashdump kernel...
[  114.082383] Bye!           
  1. 在dump vmcore時會報錯,還需要修改個配置檔案/etc/sysconfig/kdump.conf,該檔案儲存了一些變量,在加載和儲存的時候會用到,預設的參數可能不适合:
#the kdump kernel version string.
#KDUMP_KVER="`uname -r`"

#this will be passed to the kdump kernel as kdump kernel command line
#KDUMP_CMDLINE="`cat /proc/cmdline`"

#the kernel image for kdump
#KDUMP_KIMAGE="/boot/bzImage-${KDUMP_KVER}"

#Where to save the vmcore
#KDUMP_VMCORE_PATH="/var/crash/`date +"%Y-%m-%d"`"

#the arguments to makedumpfile
#MAKEDUMPFILE_ARGS="--dump-dmesg -x /boot/vmlinux-`uname -r`"    #該處為新增注釋掉行           

接着重新開機再次重複上面步驟,觀察序列槽輸出,在/var/crash目錄下會生成vmcore檔案:

Saving a vmcore to /var/crash/2018-03-09.

Checking for memory holes                         : [  0.0 %] /                  
Checking for memory holes                         : [100.0 %] |                  [   60.677885] Bluetooth: Core ver 2.22
[   60.681624] NET: Registered PF_BLUETOOTH protocol family
[   60.687045] Bluetooth: HCI device and connection manager initialized
[   60.707417] Bluetooth: HCI socket layer initialized
[   60.712391] Bluetooth: L2CAP socket layer initialized
[   60.729797] Bluetooth: SCO socket layer initialized
[   61.116047] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[   61.121458] Bluetooth: BNEP filters: protocol multicast
[   61.143609] Bluetooth: BNEP socket layer initialized

Copying data                                      : [  0.0 %] \                  
Copying data                                      : [  4.9 %] -        eta: 2m20s
Copying data                                      : [  6.0 %] /        eta: 2m26s
Copying data                                      : [ 19.7 %] |         eta: 2m0s
Copying data                                      : [100.0 %] \           eta: 0s           

自動生成vmcore

上面步驟确認了kdump功能正常,kdump自帶有啟動腳本,可以自動完成上面的操作。

本人環境路徑為/etc/rc5.d/S56kdump,具體實作功能包括:加載dump-capture kernel和儲存vmcore檔案:

....
if [ -f /etc/sysconfig/kdump.conf ]; then                              #會解析配置擷取變量
        . /etc/sysconfig/kdump.conf
else
        echo "no /etc/sysconfig/kdump.conf"
        exit 1;
fi

do_check()                      # 檢查依賴工具和參數是否正确
{
  ....
}

do_save_vmcore()         # 觸發panic時執行儲存vmcore檔案
{
	...
}

do_start()                       #檢查kexec_crash_loaded變量是否為1,cmdline是否包含crashkernel,             
{                                     # 都滿足的情況下加載dump-capture kernel
	...
}
	...           

修改kdump.conf,可以根據自己的環境設定:

樹莓派4B進階11-基于arm32 raspberry開啟kdump(1)

重新開機,接着手動觸發panic,确認是否會自動加載dump-capturekernel和生成vmocre。

有疑問歡迎留言讨論,轉載請注明出處!

繼續閱讀