Kdump是在系統(tǒng)崩潰、死鎖或死機時用來轉(zhuǎn)儲內(nèi)存運行參數(shù)的一個工具和服務(wù),是一種新的crash dump捕獲機制,用來捕獲kernel crash(內(nèi)核崩潰)的時候產(chǎn)生的crash dump。
Kdump 使用兩個內(nèi)核:生產(chǎn)內(nèi)核和捕獲內(nèi)核。生產(chǎn)內(nèi)核是一個普通內(nèi)核,它使用特殊的 kdump 特定標(biāo)志啟動。我們需要告訴生產(chǎn)內(nèi)核保留一些物理內(nèi)存,用于加載捕獲內(nèi)核。我們需要提前加載捕獲內(nèi)核,因為在崩潰發(fā)生的那一刻,由于內(nèi)核損壞,無法從磁盤讀取任何數(shù)據(jù)。
生產(chǎn)內(nèi)核是捕獲內(nèi)核服務(wù)的對像。捕獲內(nèi)核會在生產(chǎn)內(nèi)核崩潰時啟動起來,與相應(yīng)的ramdisk一起組建一個微環(huán)境,用以對生產(chǎn)內(nèi)核下的內(nèi)存進行收集和轉(zhuǎn)存。
第一個內(nèi)核保留了內(nèi)存的一部分給第二內(nèi)核啟動用。由于kdump利用kexec啟動捕獲內(nèi)核,繞過了 BIOS,所以第一個內(nèi)核的內(nèi)存得以保留。這是內(nèi)核崩潰轉(zhuǎn)儲的本質(zhì)。
dump原理
為了在生產(chǎn)內(nèi)核崩潰時能順利啟動捕獲內(nèi)核,捕獲內(nèi)核以及它的ramdisk是事先放到生產(chǎn)內(nèi)核的內(nèi)存中的。
生產(chǎn)內(nèi)核的內(nèi)存是通過/proc/vmcore這個文件交給捕獲內(nèi)核的。為了生成它,用戶工具在生產(chǎn)內(nèi)核中分析出內(nèi)存的使用和分布等情況,然后把這些信息綜合起來生成一個ELF頭文件保存起來。
捕獲內(nèi)核被引導(dǎo)時會被同時傳遞這個ELF文件頭的地址,通過分析它,捕獲內(nèi)核就可以生成出/proc/vmcore。有了/proc/vmcore這個文件,捕獲內(nèi)核的ramdisk中的腳本就可以通過通常的文件讀寫和網(wǎng)絡(luò)來實現(xiàn)各種策略了。
注意,在啟動時,kdump保留了一定數(shù)量的重要的內(nèi)存,為了計算系統(tǒng)需要的真正最小內(nèi)存,加上kdump使用的內(nèi)存數(shù)量,以決定真正的最小內(nèi)存的需求。

支持架構(gòu)
x86,x86_64,arm,arm64,ppc,s390,sh
二、kexec機制
kexec簡介
Kexec是基于kexec機制工作的,因此先了解一下Kexec。
kexec是一個快速啟動機制,允許通過已經(jīng)運行的內(nèi)核的上下文啟動一個Linux內(nèi)核,不需要經(jīng)過BIOS。(BIOS可能會消耗很多時間,特別是帶有眾多數(shù)量的外設(shè)的大型服務(wù)器。這種辦法可以為經(jīng)常啟動機器的開發(fā)者節(jié)省很多時間。)
Kexec的實現(xiàn)包括2個組成部分:
** 一是內(nèi)核空間的系統(tǒng)調(diào)用:kexec_load() **,負責(zé)在生產(chǎn)內(nèi)核(production kernel 或 first kernel)啟動時將捕獲內(nèi)核(capture kernel或sencond kernel)加載到指定地址。
** 二是用戶空間的工具kexec-tools **,他將捕獲內(nèi)核的地址傳遞給生產(chǎn)內(nèi)核,從而在系統(tǒng)崩潰的時候能夠找到捕獲內(nèi)核的地址并運行。沒有kexec就沒有kdump。先有kexec實現(xiàn)了在一個內(nèi)核中可以啟動另一個內(nèi)核,才讓kdump有了用武之地。
kexec_load()
kexec 在 kernel 里以一個系統(tǒng)調(diào)用kexec_load()的形式提供給用戶。這個系統(tǒng)調(diào)用主要用來把另一個內(nèi)核和其 ramdisk 加載到當(dāng)前內(nèi)核中。在 kdump中,捕獲內(nèi)核只能使用事先預(yù)留的一小段內(nèi)存。
生產(chǎn)內(nèi)核的內(nèi)存鏡像會被以/proc/vmcore的形式提供給用戶。這是一個 ELF格式的方件,它的頭是由用戶空間工具 kexec 生成并傳遞來的。在系統(tǒng)崩潰時,系統(tǒng)最后會調(diào)用machine_kexec()。這通常是一個硬件相關(guān)的函數(shù)。它會引導(dǎo)捕獲內(nèi)核,從而完成 kdump 的過程。
kexec-tools
kdump 的很大一部分工作都是在用戶空間內(nèi)完成的。與 kexec相關(guān)的集中在一個叫kexec-tools的工具中的kexec程序中。
該程序主要是為調(diào)用kexec_load()收集各種信息,然后調(diào)用之。這些信息主要包括 purgatory 的入口地址,還有一組由struct kexec_segment描述的信息。

最后,附上一張圖,看下kdump和kexec整個的工作流程。

三、kdump使用
內(nèi)核配置
修改內(nèi)核中以下的配置宏,可在.config文件中修改,或者通過make menuconfig修改
CONFIG_KEXEC=y
CONFIG_CRASH_DUMP=y
CONFIG_PROC_VMCORE=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
CONFIG_DEBUG_INFO=y
確認修改成功
root@firefly:/sys/kernel# ls /sys/kernel/ | grep kexec
kexec_crash_loaded
kexec_crash_size
kexec_loaded
root@firefly:~# ls /proc/ | grep kcore
kcore
如果出現(xiàn)proc/kcore,kexec相關(guān)節(jié)點說明配置生效了。
配置預(yù)留內(nèi)存
預(yù)留內(nèi)存的4種形式
預(yù)留內(nèi)存的設(shè)置一般有4種形式:
- 第一種是最常用的,直接通過size指定預(yù)留的大小,offset指定預(yù)留內(nèi)存地址的起始位置。不過,offset一般不指定,對于一般用戶來講,很難確定預(yù)留內(nèi)存惡起始位置。
crashkernel=size[KMG][@offset[KMG]]
- 第二種方式會根據(jù)系統(tǒng)的內(nèi)存大小自動選擇預(yù)留內(nèi)存的大小,比較靈活。
crashkernel=range1:size1[,range2:size,...][@offset]
舉例
crashkernel=512M-2G:64M,2G-6G:256M,6G-8G:512M,8G-:768M
參數(shù)含義如下:
如果RAM大小小于512M,則不預(yù)留內(nèi)存。
如果RAM大小為512M - 2G,則預(yù)留 64M。
如果RAM大小為2 - 6G,則預(yù)留 256M。
如果RAM大小大于8G,則預(yù)留768 M。
- 一般我們會在0~4G范圍內(nèi)預(yù)留內(nèi)存。如果系統(tǒng)內(nèi)存大于4G,則支持在4G以上預(yù)留內(nèi)存,比如X86_64架構(gòu)。當(dāng)指定high參數(shù)時,系統(tǒng)會在0~4G和4G以上預(yù)留兩段內(nèi)存。默認情況下,x86_64會在4G以下預(yù)留256M內(nèi)存。
crashkernel=size[KMG],hign
- low參數(shù)主要是配合high來使用的。如果覺得4G以下默認預(yù)留的256M太多了,可以手動指定預(yù)留內(nèi)存。
crashkernel=size[KMG],low
在ARM上配置預(yù)留內(nèi)存
在X86-64主機上一般是修改/etc/default/grup
中的參數(shù)來配置及檢查, 但是在嵌入式設(shè)備上因為是裁剪的系統(tǒng),并沒有g(shù)rup這個文件。
但我們可以知道,配置grup文件的目的就是更改cmdline中的內(nèi)容,那我們?nèi)绾稳ジ腸mdline的內(nèi)容呢?提供以下幾個思路:
- 在uboot中添加:在源碼中添加或者通過setenv配置bootargs變量
這里我們選擇在dts中修改。
vim kernel/arch/arm64/boot/dts/rockchip/rk3399-linux.dtsi
當(dāng)前使用的設(shè)備RAM已經(jīng)是4G,所以預(yù)留的是256M
root@firefly:~# free -m
total used free shared buff/cache available
Mem: 3583 194 3154 8 234 3351
Swap: 0 0 0

重新編譯燒寫內(nèi)核,看到設(shè)備啟動時,已經(jīng)加入了啟動參數(shù)。

查看啟動參數(shù)是否生效
root@firefly:~# cat /proc/iomem | grep Crash
e5e00000-f5dfffff : Crash kernel
確認分配內(nèi)存大小
root@firefly:~# cat /sys/kernel/kexec_crash_size
268435456
預(yù)留內(nèi)存大小評估
在某些情況下,我們需要正確評估預(yù)留內(nèi)存的大小,主要從以下2個方面考慮。
- 系統(tǒng)內(nèi)kernel,initrd,romfs,devices driver的大小。
- 捕獲內(nèi)核啟動cpu的個數(shù)。啟動cpu越多,需要的內(nèi)存越大。一般情況下,捕獲內(nèi)核一般啟動一個CPU核即可。
/proc/iomem表示的是系統(tǒng)的物理內(nèi)存布局, System RAM entry表示當(dāng)前系統(tǒng)可用的預(yù)留內(nèi)存。例如,我當(dāng)前設(shè)備的內(nèi)存為3.8G,預(yù)留800M內(nèi)存也是足夠的。
root@firefly:~# cat /proc/iomem | grep System
00200000-083fffff : System RAM
0a200000-f7ffffff : System RAM
編譯kexec工具
- 從下面的網(wǎng)站下載最新的kexec-tools源碼包。
http:///pub/linux/utils/kernel/kexec/kexec-tools.tar.gz
tar xvpzf kexec-tools-2.0.26.tar.gz
LDFLAGS=-static ./configure ARCH=arm64 --build=x86_64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu --without-xen
這里使用靜態(tài)編譯。
make
- 將build目錄下sbin/kexec拷貝至rootfs/usr/sbin/中。
root@firefly:~/kexec/sbin# kexec -v
kexec-tools 2.0.26
查看kexec參數(shù)。
root@firefly:~# kexec -h
kexec-tools 2.0.26
Usage: kexec [OPTION]... [kernel]
Directly reboot into a new kernel
-h, Print this help.
-v, --version Print the version of kexec.
-f, --force Force an immediate kexec,
don't call shutdown.
-i, --no-checks Fast reboot, no memory integrity checks.
-x, --no-ifdown Don't bring down network interfaces.
-y, --no-sync Don't sync filesystems before kexec.
-l, --load Load the new kernel into the
current kernel.
-p, --load-panic Load the new kernel for use on panic.
-u, --unload Unload the current kexec target kernel.
If capture kernel is being unloaded
specify -p with -u.
-e, --exec Execute a currently loaded kernel.
--exec-live-update Execute a currently loaded xen image after
storing the state required to live update.
-t, --type=TYPE Specify the new kernel is of this type.
--mem-min=<addr> Specify the lowest memory address to
load code into.
--mem-max=<addr> Specify the highest memory address to
load code into.
--reuseinitrd Reuse initrd from first boot.
--print-ckr-size Print crash kernel region size.
--load-preserve-context Load the new kernel and preserve
context of current kernel during kexec.
--load-jump-back-helper Load a helper image to jump back
to original kernel.
--load-live-update Load the new kernel to overwrite the
running kernel.
--entry=<addr> Specify jump back address.
(0 means it's not jump back or
preserve context)
to original kernel.
-s, --kexec-file-syscall Use file based syscall for kexec operation
-c, --kexec-syscall Use the kexec_load syscall for for compatibility
with systems that don't support -s (default)
-a, --kexec-syscall-auto Use file based syscall for kexec and fall
back to the compatibility syscall when file based
syscall is not supported or the kernel did not
understand the image
-d, --debug Enable debugging to help spot a failure.
-S, --status Return 1 if the type (by default crash) is loaded,
0 if not.
Supported kernel file types and options:
vmlinux
An ARM64 ELF image, big or little endian.
Typically vmlinux or a stripped version of vmlinux.
Image
An ARM64 binary image, uncompressed, big or little endian.
Typically an Image file.
uImage
An ARM64 U-boot uImage file, compressed or not, big or little endian.
zImage
An ARM64 zImage, compressed, big or little endian.
Typically an Image.gz or Image.lzma file.
Architecture options:
--append=STRING Set the kernel command line to STRING.
--command-line=STRING Set the kernel command line to STRING.
--dtb=FILE Use FILE as the device tree blob.
--initrd=FILE Use FILE as the kernel initial ramdisk.
--serial=STRING Name of console used for purgatory printing. (e.g. ttyAMA0)
--ramdisk=FILE Use FILE as the kernel initial ramdisk.
--reuse-cmdline Use kernel command line from running system.
注意以下幾個參數(shù)
-d: 執(zhí)行kexec指令時會打印調(diào)試信息
-p: 將內(nèi)核加載到預(yù)留內(nèi)存中,panic時自動啟動capture內(nèi)核。
-l: 將內(nèi)核加載到預(yù)留內(nèi)存中
--append : capture內(nèi)核的command line的內(nèi)容
--t: 內(nèi)核的類型,比如vmlinux,Image,uImage,zImage
--intrd:指定initrd
--reuseinitrd:復(fù)用第一個內(nèi)核的initrd
--dtb:指定設(shè)備樹
vmlinux,Image,uImage,zImage區(qū)別參考:secure boot (一)FIT Image
四、測試
配置kexec
嘗試手動配置kexec
kexec --t vmlinux -p /root/var/vmlinux --ramdisk /root/var/ramdisk.img --append='storagemedia=emmc androidboot.storagemedia=emmc androidboot.mode=normal storagenode=sdhci@fe330000 androidboot.slot_suffix= androidboot.serialno=3fdce35e50641399 ro rootwait earlycon=uart8250,mmio32,0xff1a0000 swiotlb=1 console=ttyFIQ0 root=PARTLABEL=rootfs rootfstype=ext4 overlayroot=device:dev=PARTLABEL=userdata,fstype=ext4,mkfs=1 coherent_pool=1m systemd.gpt_auto=0 cgroup_enable=memory swapaccount=1 crashkernel=256M'
command line 可以通過cat /proc/cmdline 查看。
ramdisk.img 也可以叫做initrd.img, 它是一個小文件系統(tǒng),麻雀雖小五臟俱全,它介于kernel 和 文件系統(tǒng)之間。kernel 啟動后會先執(zhí)行ramdisk.img 里面的init, 掛載這里的小型文件系統(tǒng),接著開始完成一些必要的操作,最后在交給文件系統(tǒng)/sbin/init進行執(zhí)行。
查看捕獲內(nèi)核的加載狀態(tài) 0:未加載,1:已加載
root@firefly:~# cat /sys/kernel/kexec_crash_loaded
1
查看捕獲內(nèi)核的大小
root@firefly:~# cat /sys/kernel/kexec_crash_size
268435456
確認kexec_load_disabled的狀態(tài)
root@firefly:~# cat /proc/sys/kernel/kexec_load_disabled
0
kexec_load_disabled:表示kexec_load系統(tǒng)調(diào)用是否被禁止,此系統(tǒng)調(diào)用用于kdump。當(dāng)發(fā)生了一次kexec_load后,此值會自動設(shè)置為1。
測試啟動捕獲內(nèi)核
在前面的準(zhǔn)備工作完成后,如果觸發(fā)系統(tǒng)崩潰,系統(tǒng)將重新引導(dǎo)到轉(zhuǎn)儲-捕獲內(nèi)核,觸發(fā)點位于panic()、die()、die_nmi()和sysrq處理程序中。接下來我將通過 魔術(shù)鍵來觸發(fā)系統(tǒng)panic。
開啟sysrq
echo 1 > /proc/sys/kernel/sysrq
觸發(fā)sysrq
echo c > /proc/sysrq-trigger
觸發(fā)sysrq后,系統(tǒng)重啟,串口打印出標(biāo)志性 log:Bye!Starting crashdump kernel...。
[06:48:37]root@firefly:~# echo c > /proc/sysrq-trigger
[06:48:37][ 28.817657] sysrq: SysRq : Trigger a crash
[06:48:37][ 28.818172] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[06:48:37][ 28.818894] pgd = ffffffc0deb9d000
[06:48:37][ 28.819326] [00000000] *pgd=0000000000000000, *pud=0000000000000000
....................
[06:48:37][ 28.950698] [<ffffff80085abe98>] sysrq_handle_crash+0x24/0x30
[06:48:37][ 28.951218] [<ffffff80085ac968>] __handle_sysrq+0xa0/0x14c
[06:48:37][ 28.951713] [<ffffff80085acd94>] write_sysrq_trigger+0x5c/0x74
[06:48:37][ 28.952246] [<ffffff8008244928>] proc_reg_write+0xa8/0xcc
[06:48:37][ 28.952744] [<ffffff80081e86bc>] __vfs_write+0x48/0xe8
[06:48:37][ 28.953214] [<ffffff80081e8fa8>] vfs_write+0xa8/0x15c
[06:48:37][ 28.953674] [<ffffff80081e9948>] SyS_write+0x5c/0xb0
[06:48:37][ 28.954123] [<ffffff8008082f70>] el0_svc_naked+0x24/0x28
[06:48:37][ 28.954609] Code: 52800020 b90a1c20 d5033e9f d2800001 (39000020)
[06:48:37][ 28.955167] SMP: stopping secondary CPUs
[06:48:37][ 28.955899] Starting crashdump kernel...
[06:48:37][ 28.956264] Bye!
[06:48:51][ 0.000000] Booting Linux on physical CPU 0x101
[06:48:51][ 0.000000] Initializing cgroup subsys cp 0.000000] Initializing cgrouys cpu
[06:48:51][ 0.000000] Initializys cpuacct
[06:48:51][ 0.000000] Linux version 4.4.194+ (zhongyi@ubunty: b1730021dd51a88c333473088af3a402491b4c23) (gcc version 6.3.1 20170404 (Linaro GCC 6.3-2017.05SMP Fri Mar 3 07:48:00 CST 2023
[06:48:51][ 0.000000] Boot CPU: AArch64 Processor [410fd082]
[06:48:51][ 0.000000] earlycon: Early serial console at MMIO32 0xff1a0000 (opti '')
[06:48:51][ 0.000000] bootconsole [uart0] enabled
[06:48:51][ 0.000000] cannot allocate crashkernel (size:0x10000000)
[06:48:51][ 0.000000] Reserving 1KB of memory at 0xf5dff000 for elfcorehdr
[06:48:51][ 0.000000] psci: probing for conduit method from DT.
[06:48:51][ 0.000000] psci: PSCIv1.0 detected in firmware.
[06:48:51][ 0.000000] psci: Using standard PSCI v0.2 function IDs
[06:48:52][ 0.000000] psci: Trusted OS migration not required
[06:48:52][ 0.000000] PERCPU: Embedded 21 pages/cpu @ffffffc035cf1000 s46440 r8192 d31384 u86016
[06:48:52][ 0.000000] Detected PIPT I-cache on CPU0
[06:48:52][ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 64512
[06:48:52][ 0.000000] Kernel command line: storagemedia=emmc androidboot.storagemedia=emmc androidboot.mode=normal storagenode=sdhci@fe330000 androidboot.slot_suffix= androidboot.serialno=3fdce35e50641399 ro rootwait earlycon=uart8250,mmio32,0xff1a0000 swiotlb=1 console=ttyFIQ0 root=PARTLABEL=rootfs rootfstype=ext4 overlayroot=device:dev=PARTLABEL=userdata,fstype=ext4,mkfs=1 coherent_pool=1m systemd.gpt_auto=0 cgroup_enable=memory swapaccount=1 crashkernel=256M
[06:48:52][ 0.000000] PID hash table entries: 1024 (order: 1, 8192 bytes)
[06:48:52][ 0.000000] Dentry cache hash table entries: 32768 (order: 6, 262144 bytes)
[06:48:52][ 0.000000] Inode-cache hash table entries: 16384 (order: 5, 131072 bytes)
[06:48:52][ 0.000000] software IO TLB: mapped [mem 0xf5c51000-0xf5c91000] (0MB)
[06:48:52][ 0.000000] Memory: 208908K/262144K available (14782K kernel code, 2146K rwdata, 6988K rodata, 1216K init, 780K bss, 53236K reserved, 0K cma-reserved)
[06:48:52][ 0.000000] Virtual kernel memory layout:
[06:48:52][ 0.000000] modules : 0xffffff8000000000 - 0xffffff8008000000 ( 128 MB)
[06:48:52][ 0.000000] vmalloc : 0xffffff8008000000 - 0xffffffbdbfff0000 ( 246 GB)
[06:48:52][ 0.000000] .init : 0xffffff80095d0000 - 0xffffff8009700000 ( 1216 KB)
[06:48:52][ 0.000000] .text : 0xffffff8008080000 - 0xffffff8008ef0000 ( 14784 KB)
[06:48:52][ 0.000000] .rodata : 0xffffff8008ef0000 - 0xffffff80095d0000 ( 7040 KB)
[06:48:52][ 0.000000] .data : 0xffffff8009700000 - 0xffffff8009918808 ( 2147 KB)
[06:48:52][ 0.000000] vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000 ( 8 GB maximum)
[06:48:52][ 0.000000] 0xffffffbdc0978000 - 0xffffffbdc0d78000 ( 4 MB actual)
[06:48:52][ 0.000000] fixed : 0xffffffbffe7fb000 - 0xffffffbffec00000 ( 4116 KB)
[06:48:52][ 0.000000] PCI I/O : 0xffffffbffee00000 - 0xffffffbfffe00000 ( 16 MB)
[06:48:52][ 0.000000] memory : 0xffffffc025e00000 - 0xffffffc035e00000 ( 256 MB)
[06:48:52][ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=6, Nodes=1
.........................................
[06:48:54][ 2.313003] rockchip-drm display-subsystem: bound ff940000.hdmi (ops dw_hdmi_rockchip_ops)
[06:48:54][ 2.314207] i2c i2c-10: of_i2c: modalias failure on /dp@fec00000/ports
[06:48:54][ 2.315077] rockchip-drm display-subsystem: bound fec00000.dp (ops cdn_dp_component_ops)
[06:48:54][ 2.315815] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[06:48:54][ 2.316404] [drm] No driver support for vblank timestamp query.
[06:48:54][ 2.317133] rockchip-drm display-subsystem: connector[HDMI-A-1] can't found any modes
.................................................
[06:48:58][ 6.180434] [dhd] dhd_conf_set_path_params : Final conf_path=/vendor/etc/firmware/config.txt
[06:48:58][ 6.313492] [dhd] dhd_conf_set_txglom_params : txglom_mode=multi-desc
[06:48:58][ 6.314159] [dhd] dhd_conf_set_txglom_params : txglomsize=36, deferred_tx_len=0
[06:48:58][ 6.314868] [dhd] dhd_conf_set_txglom_params : txinrx_thres=128d_txminmax=-1
[06:48:58][ 6.315529] [ddhd_conf_set_txglom_params : tx__offset=0, txctl_tmo_fix=300
[06:48:58][ 6.316245] [dhd] dhd_conf_get_disable_proptx : fw_proptx=1, disable_proptx=-1
[06:48:58][ 6.380768] [dhd] dhd_conf_map_country_list : CN/38
[06:48:58][ 6.381222] [dhd] dhd_conf_set_country : set country CN, revision 38
[06:48:58][ 6.385992] [dhd] dhd_conf_set_country : Country code: CN (CN/38)
[06:48:58][ OK ] Started Network Manager.
[06:48:58][ OK ] Reached target Network.
[06:48:58] Starting Permit User Sessions...
[06:48:58] Starting OpenBSD Secure Shell server...
[06:48:58][ OK ] Started Permit User Sessions.
[06:48:58] Starting Hold until boot process finishes up...
[06:48:58][ OK ] Started Hold until boot process finishes up.
[06:48:58][ OK ] Started Serial Getty on ttyFIQ0.
[06:48:58] Starting Set console scheme...
[06:48:58][ OK ] Started Set console scheme.
[06:48:58][ OK ] Created slice system-getty.slice.
[06:48:58][ OK ] Started Getty on tty1.
[06:48:58][ OK ] Reached target Login Prompts.
[06:48:58][ OK ] Started OpenBSD Secure Shell server.
[06:48:58][ OK ] Started Adbd for linux.
[06:48:58][ OK ] Started Setup rockchip platform environment.
[06:48:58] Starting Light Display Manager...
[06:48:58][ OK ] Reached target Multi-User System.
[06:48:59][ OK ] Started Light Display Manager.
[06:48:59][ OK ] Reached target Graphical Interface.
[06:48:59] Starting Update UTMP about System Runlevel Changes...
[06:48:59][ OK ] Started Update UTMP about System Runlevel Changes.
[06:48:59]
[06:48:59]Ubuntu 18.04.6 LTS firefly ttyFIQ0
[06:49:39]root@firefly:~# ls -al /proc/vmcore
[06:49:41]-r-------- 1 root root 3885387776 Mar 5 22:49 /proc/vmcore
[06:50:24]root@firefly:~# ls -al --block-size=m /proc/vmcore
系統(tǒng)正常啟動后,就可以將/proc/vmcore文件拷貝出來在ubuntu上用crash工具分析。
五、常見問題及解決辦法
在ARM平臺上,系統(tǒng)崩潰后卡死,未啟動第二內(nèi)核
不清楚是宿主機的原因還是代碼原因,目前主線的 Linux kernel 代碼在執(zhí)行命令使第一個內(nèi)核崩潰之后,跳轉(zhuǎn)到第二個內(nèi)核的過程中卡死,在社區(qū)上也有其他人遇到了類似的情況并給出了補丁,但是并沒有合并到主線,不過目前為了演示暫時不考慮為何原因?qū)е逻@個問題的出現(xiàn),如果你的 arm64 不存在這個問題,那么就不需要打這個補丁了。奉上補丁如下:
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index aa9c94113700..3b0350d20e31 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -234,19 +234,12 @@ static void machine_kexec_mask_interrupts(void)
for_each_irq_desc(i, desc) {
struct irq_chip *chip;
- int ret;
chip = irq_desc_get_chip(desc);
if (!chip)
continue;
- /*
- * First try to remove the active state. If this
- * fails, try to EOI the interrupt.
- */
- ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
-
- if (ret && irqd_irq_inprogress(&desc->irq_data) &&
+ if (irqd_irq_inprogress(&desc->irq_data) &&
chip->irq_eoi)
chip->irq_eoi(&desc->irq_data);
還有一點需要說明的就是在 Ubuntu 默認倉庫的 crash 不支持最新版本的 Linux 內(nèi)核,需要更新到 7.2.5 版本才可以。
沒有生產(chǎn)vmcore
按照kdump執(zhí)行流程,確定問題來自那個階段。
預(yù)留內(nèi)存失敗
預(yù)留內(nèi)存過大,設(shè)備沒有足夠的可用內(nèi)存。默認會在0~4G預(yù)留內(nèi)存。比如預(yù)留512M的空間,而在0~4G并沒有可用的512M空間,就會導(dǎo)致預(yù)留失敗。
加載內(nèi)核失敗
是否預(yù)留內(nèi)存,crashkernel是否配置?
預(yù)留內(nèi)存成功:嘗試使用kexec -d -p 查看失敗的具體原因。
第二內(nèi)核啟動失敗
打印出bye后沒有任何信息輸出,可能是第二內(nèi)核可能未配置串口,earlycon/console
oom后卡死,可能是預(yù)留內(nèi)存太小。
驅(qū)動初始化失敗。有些驅(qū)動,比如dma32,可能只能使用0~4G內(nèi)存,在4G以上預(yù)留內(nèi)存會導(dǎo)致驅(qū)動加載失敗。
makedumpfile失敗
加上-D,打印出debug選項,查看失敗原因。
用戶態(tài)工具問題
kernel,kexec,makedumpfile,crash匹配問題,更新到最新的工具。
六、本文參考
https://lore./lkml/ba0c6804-51a3-f36e-a67e-20ce84961451@arm.com/T/
https://www.cnblogs.com/shineshqw/articles/2359114.html
https://wiki./title/Kdump
https://kaiwantech./2017/07/13/setting-up-kdump-and-crash-for-arm-32-an-ongoing-saga/
https:///post/7115949300147814430
https://blog.csdn.net/Luckiers/article/details/124581570