程序员开发实例大全宝库

网站首页 > 编程文章 正文

树莓派4B高级11-基于arm raspberry开启kdump(1)

zazugpt 2024-08-10 22:49:01 编程文章 69 ℃ 0 评论

平常工作主要涉及系统性能稳定性的工作,而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"

增大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,可以根据自己的环境设置:

重启,接着手动触发panic,确认是否会自动加载dump-capturekernel和生成vmocre。


有疑问欢迎留言讨论,转载请注明出处!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表