簡介
Kdump是在系統崩潰、死鎖或死機時用來轉儲內存運行參數的一個工具和服務,是一種新的crash dump捕獲機制,用來捕獲kernel crash(內核崩潰)的時候產生的crash dump。
Kdump 使用兩個內核:生產內核和捕獲內核。生產內核是一個普通內核,它使用特殊的 kdump 特定標志啟動。我們需要告訴生產內核保留一些物理內存,用于加載捕獲內核。我們需要提前加載捕獲內核,因為在崩潰發生的那一刻,由于內核損壞,無法從磁盤讀取任何數據。
生產內核是捕獲內核服務的對像。捕獲內核會在生產內核崩潰時啟動起來,與相應的ramdisk一起組建一個微環境,用以對生產內核下的內存進行收集和轉存。
第一個內核保留了內存的一部分給第二內核啟動用。由于kdump利用kexec啟動捕獲內核,繞過了 BIOS,所以第一個內核的內存得以保留。這是內核崩潰轉儲的本質。
dump原理
為了在生產內核崩潰時能順利啟動捕獲內核,捕獲內核以及它的ramdisk是事先放到生產內核的內存中的。
生產內核的內存是通過/proc/vmcore這個文件交給捕獲內核的。為了生成它,用戶工具在生產內核中分析出內存的使用和分布等情況,然后把這些信息綜合起來生成一個ELF頭文件保存起來。
捕獲內核被引導時會被同時傳遞這個ELF文件頭的地址,通過分析它,捕獲內核就可以生成出/proc/vmcore。有了/proc/vmcore這個文件,捕獲內核的ramdisk中的腳本就可以通過通常的文件讀寫和網絡來實現各種策略了。
注意,在啟動時,kdump保留了一定數量的重要的內存,為了計算系統需要的真正最小內存,加上kdump使用的內存數量,以決定真正的最小內存的需求。
支持架構
x86,x86_64,arm,arm64,ppc,s390,sh
kexec機制
kexec簡介
Kexec是基于kexec機制工作的,因此先了解一下Kexec。
kexec是一個快速啟動機制,允許通過已經運行的內核的上下文啟動一個Linux內核,不需要經過BIOS。(BIOS可能會消耗很多時間,特別是帶有眾多數量的外設的大型服務器。這種辦法可以為經常啟動機器的開發者節省很多時間。)
Kexec的實現包括2個組成部分:
** 一是內核空間的系統調用:kexec_load() **,負責在生產內核(production kernel 或 first kernel)啟動時將捕獲內核(capture kernel或sencond kernel)加載到指定地址。
** 二是用戶空間的工具kexec-tools **,他將捕獲內核的地址傳遞給生產內核,從而在系統崩潰的時候能夠找到捕獲內核的地址并運行。沒有kexec就沒有kdump。先有kexec實現了在一個內核中可以啟動另一個內核,才讓kdump有了用武之地。
kexec_load()
kexec 在 kernel 里以一個系統調用 kexec_load()的形式提供給用戶。這個系統調用主要用來把另一個內核和其 ramdisk 加載到當前內核中。在 kdump中,捕獲內核只能使用事先預留的一小段內存。
生產內核的內存鏡像會被以 /proc/vmcore 的形式提供給用戶。這是一個 ELF格式的方件,它的頭是由用戶空間工具 kexec 生成并傳遞來的。在系統崩潰時,系統最后會調用machine_kexec()。這通常是一個硬件相關的函數。它會引導捕獲內核,從而完成 kdump 的過程。
kexec-tools
kdump 的很大一部分工作都是在用戶空間內完成的。與 kexec相關的集中在一個叫kexec-tools的工具中的kexec程序中。
該程序主要是為調用 kexec_load()收集各種信息,然后調用之。這些信息主要包括 purgatory 的入口地址,還有一組由 struct kexec_segment描述的信息。
最后,附上一張圖,看下kdump和kexec整個的工作流程。
kdump使用
內核配置
修改內核中以下的配置宏,可在.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
如果出現proc/kcore,kexec相關節點說明配置生效了。
配置預留內存
預留內存的4種形式
預留內存的設置一般有4種形式:
第一種是最常用的,直接通過size指定預留的大小,offset指定預留內存地址的起始位置。不過,offset一般不指定,對于一般用戶來講,很難確定預留內存惡起始位置。
crashkernel=size[KMG][@offset[KMG]]
第二種方式會根據系統的內存大小自動選擇預留內存的大小,比較靈活。
crashkernel=range1:size1[,range2:size,...][@offset]
舉例
crashkernel=512M-2G:64M,2G-6G:256M,6G-8G:512M,8G-:768M
參數含義如下:
如果RAM大小小于512M,則不預留內存。
如果RAM大小為512M - 2G,則預留 64M。
如果RAM大小為2 - 6G,則預留 256M。
如果RAM大小大于8G,則預留768 M。
一般我們會在0~4G范圍內預留內存。如果系統內存大于4G,則支持在4G以上預留內存,比如X86_64架構。當指定high參數時,系統會在0~4G和4G以上預留兩段內存。默認情況下,x86_64會在4G以下預留256M內存。
crashkernel=size[KMG],hign
low參數主要是配合high來使用的。如果覺得4G以下默認預留的256M太多了,可以手動指定預留內存。
crashkernel=size[KMG],low
在ARM上配置預留內存
在X86-64主機上一般是修改/etc/default/grup中的參數來配置及檢查, 但是在嵌入式設備上因為是裁剪的系統,并沒有grup這個文件。
但我們可以知道,配置grup文件的目的就是更改cmdline中的內容,那我們如何去更改cmdline的內容呢?提供以下幾個思路:
在dts中中添加:修改chosen
在BoardConfig中添加
在uboot中添加:在源碼中添加或者通過setenv配置bootargs變量
在android的Makefile中添加
這里我們選擇在dts中修改。
vim?kernel/arch/arm64/boot/dts/rockchip/rk3399-linux.dtsi? ?
當前使用的設備RAM已經是4G,所以預留的是256M
root@firefly:~#?free?-m ??????????????total????????used????????free??????shared??buff/cache???available Mem:???????????3583?????????194????????3154???????????8?????????234????????3351 Swap:?????????????0???????????0???????????0
?
?
重新編譯燒寫內核,看到設備啟動時,已經加入了啟動參數。
查看啟動參數是否生效
root@firefly:~#?cat?/proc/iomem?|?grep?Crash e5e00000-f5dfffff?:?Crash?kernel
確認分配內存大小
root@firefly:~#?cat?/sys/kernel/kexec_crash_size 268435456
預留內存大小評估
在某些情況下,我們需要正確評估預留內存的大小,主要從以下2個方面考慮。
系統內kernel,initrd,romfs,devices driver的大小。
捕獲內核啟動cpu的個數。啟動cpu越多,需要的內存越大。一般情況下,捕獲內核一般啟動一個CPU核即可。
/proc/iomem表示的是系統的物理內存布局, System RAM entry表示當前系統可用的預留內存。例如,我當前設備的內存為3.8G,預留800M內存也是足夠的。
root@firefly:~#?cat?/proc/iomem?|?grep?System 00200000-083fffff?:?System?RAM 0a200000-f7ffffff?:?System?RAM?
編譯kexec工具
解壓源碼包。
tar?xvpzf??kexec-tools-2.0.26.tar.gz?
進入到kexec-tools中,并進行配置。
LDFLAGS=-static?./configure?ARCH=arm64?--build=x86_64-linux-gnu?--host=aarch64-linux-gnu?--target=aarch64-linux-gnu?--without-xen
這里使用靜態編譯。
然后使用make進行編譯。
make
將build目錄下sbin/kexec 拷貝至rootfs /usr/sbin/中。
root@firefly:~/kexec/sbin#?kexec?-v kexec-tools?2.0.26
查看kexec參數。
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=?Specify?the?lowest?memory?address?to ??????????????????????load?code?into. ?????--mem-max= ?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= ???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.
注意以下幾個參數
-d:?執行kexec指令時會打印調試信息? -p:?將內核加載到預留內存中,panic時自動啟動capture內核。 -l:?將內核加載到預留內存中 --append?:?capture內核的command?line的內容 --t:?內核的類型,比如vmlinux,Image,uImage,zImage --intrd:指定initrd --reuseinitrd:復用第一個內核的initrd --dtb:指定設備樹
vmlinux,Image,uImage,zImage區別參考: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, ?它是一個小文件系統,麻雀雖小五臟俱全,它介于kernel 和 文件系統之間。kernel 啟動后會先執行ramdisk.img 里面的init, 掛載這里的小型文件系統,接著開始完成一些必要的操作,最后在交給文件系統/sbin/init 進行執行。
查看捕獲內核的加載狀態 0:未加載,1:已加載
root@firefly:~#?cat?/sys/kernel/kexec_crash_loaded?
1查看捕獲內核的大小
root@firefly:~#?cat?/sys/kernel/kexec_crash_size
268435456
確認 kexec_load_disabled 的狀態
root@firefly:~#?cat?/proc/sys/kernel/kexec_load_disabled 0
kexec_load_disabled:表示kexec_load系統調用是否被禁止,此系統調用用于kdump。當發生了一次kexec_load后,此值會自動設置為1。
測試啟動捕獲內核
在前面的準備工作完成后,如果觸發系統崩潰,系統將重新引導到轉儲-捕獲內核,觸發點位于panic()、die()、die_nmi()和sysrq處理程序中。接下來我將通過 魔術鍵來觸發系統panic。
開啟sysrq
echo?1?>?/proc/sys/kernel/sysrq?
觸發sysrq
echo?c?>?/proc/sysrq-trigger
觸發sysrq后,系統重啟,串口打印出標志性 log:Bye!Starting crashdump kernel...。
[0637]root@firefly:~#?echo?c?>?/proc/sysrq-trigger [0637][???28.817657]?sysrq:?SysRq?:?Trigger?a?crash [0637][???28.818172]?Unable?to?handle?kernel?NULL?pointer?dereference?at?virtual?address?00000000 [0637][???28.818894]?pgd?=?ffffffc0deb9d000 [0637][???28.819326]?[00000000]?*pgd=0000000000000000,?*pud=0000000000000000 .................... [0637][???28.950698]?[]?sysrq_handle_crash+0x24/0x30 [0637][???28.951218]?[ ]?__handle_sysrq+0xa0/0x14c [0637][???28.951713]?[ ]?write_sysrq_trigger+0x5c/0x74 [0637][???28.952246]?[ ]?proc_reg_write+0xa8/0xcc [0637][???28.952744]?[ ]?__vfs_write+0x48/0xe8 [0637][???28.953214]?[ ]?vfs_write+0xa8/0x15c [0637][???28.953674]?[ ]?SyS_write+0x5c/0xb0 [0637][???28.954123]?[ ]?el0_svc_naked+0x24/0x28 [0637][???28.954609]?Code:?52800020?b90a1c20?d5033e9f?d2800001?(39000020)? [0637][???28.955167]?SMP:?stopping?secondary?CPUs [0637][???28.955899]?Starting?crashdump?kernel... [0637][???28.956264]?Bye! [0651][????0.000000]?Booting?Linux?on?physical?CPU?0x101 [0651][????0.000000]?Initializing?cgroup?subsys?cp????0.000000]?Initializing?cgrouys?cpu [0651][????0.000000]?Initializys?cpuacct [0651][????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?0700?CST?2023 [0651][????0.000000]?Boot?CPU:?AArch64?Processor?[410fd082] [0651][????0.000000]?earlycon:?Early?serial?console?at?MMIO32?0xff1a0000?(opti?'') [0651][????0.000000]?bootconsole?[uart0]?enabled [0651][????0.000000]?cannot?allocate?crashkernel?(size:0x10000000) [0651][????0.000000]?Reserving?1KB?of?memory?at?0xf5dff000?for?elfcorehdr [0651][????0.000000]?psci:?probing?for?conduit?method?from?DT. [0651][????0.000000]?psci:?PSCIv1.0?detected?in?firmware. [0651][????0.000000]?psci:?Using?standard?PSCI?v0.2?function?IDs [0652][????0.000000]?psci:?Trusted?OS?migration?not?required [0652][????0.000000]?PERCPU:?Embedded?21?pages/cpu?@ffffffc035cf1000?s46440?r8192?d31384?u86016 [0652][????0.000000]?Detected?PIPT?I-cache?on?CPU0 [0652][????0.000000]?Built?1?zonelists?in?Zone?order,?mobility?grouping?on.??Total?pages:?64512 [0652][????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 [0652][????0.000000]?PID?hash?table?entries:?1024?(order:?1,?8192?bytes) [0652][????0.000000]?Dentry?cache?hash?table?entries:?32768?(order:?6,?262144?bytes) [0652][????0.000000]?Inode-cache?hash?table?entries:?16384?(order:?5,?131072?bytes) [0652][????0.000000]?software?IO?TLB:?mapped?[mem?0xf5c51000-0xf5c91000]?(0MB) [0652][????0.000000]?Memory:?208908K/262144K?available?(14782K?kernel?code,?2146K?rwdata,?6988K?rodata,?1216K?init,?780K?bss,?53236K?reserved,?0K?cma-reserved) [0652][????0.000000]?Virtual?kernel?memory?layout: [0652][????0.000000]?????modules?:?0xffffff8000000000?-?0xffffff8008000000???(???128?MB) [0652][????0.000000]?????vmalloc?:?0xffffff8008000000?-?0xffffffbdbfff0000???(???246?GB) [0652][????0.000000]???????.init?:?0xffffff80095d0000?-?0xffffff8009700000???(??1216?KB) [0652][????0.000000]???????.text?:?0xffffff8008080000?-?0xffffff8008ef0000???(?14784?KB) [0652][????0.000000]?????.rodata?:?0xffffff8008ef0000?-?0xffffff80095d0000???(??7040?KB) [0652][????0.000000]???????.data?:?0xffffff8009700000?-?0xffffff8009918808???(??2147?KB) [0652][????0.000000]?????vmemmap?:?0xffffffbdc0000000?-?0xffffffbfc0000000???(?????8?GB?maximum) [0652][????0.000000]???????????????0xffffffbdc0978000?-?0xffffffbdc0d78000???(?????4?MB?actual) [0652][????0.000000]?????fixed???:?0xffffffbffe7fb000?-?0xffffffbffec00000???(??4116?KB) [0652][????0.000000]?????PCI?I/O?:?0xffffffbffee00000?-?0xffffffbfffe00000???(????16?MB) [0652][????0.000000]?????memory??:?0xffffffc025e00000?-?0xffffffc035e00000???(???256?MB) [0652][????0.000000]?SLUB:?HWalign=64,?Order=0-3,?MinObjects=0,?CPUs=6,?Nodes=1 ......................................... [0654][????2.313003]?rockchip-drm?display-subsystem:?bound?ff940000.hdmi?(ops?dw_hdmi_rockchip_ops) [0654][????2.314207]?i2c?i2c-10:?of_i2c:?modalias?failure?on?/dp@fec00000/ports [0654][????2.315077]?rockchip-drm?display-subsystem:?bound?fec00000.dp?(ops?cdn_dp_component_ops) [0654][????2.315815]?[drm]?Supports?vblank?timestamp?caching?Rev?2?(21.10.2013). [0654][????2.316404]?[drm]?No?driver?support?for?vblank?timestamp?query. [0654][????2.317133]?rockchip-drm?display-subsystem:?connector[HDMI-A-1]?can't?found?any?modes ................................................. [0658][????6.180434]?[dhd]?dhd_conf_set_path_params?:?Final?conf_path=/vendor/etc/firmware/config.txt [0658][????6.313492]?[dhd]?dhd_conf_set_txglom_params?:?txglom_mode=multi-desc [0658][????6.314159]?[dhd]?dhd_conf_set_txglom_params?:?txglomsize=36,?deferred_tx_len=0 [0658][????6.314868]?[dhd]?dhd_conf_set_txglom_params?:?txinrx_thres=128d_txminmax=-1 [0658][????6.315529]?[ddhd_conf_set_txglom_params?:?tx__offset=0,?txctl_tmo_fix=300 [0658][????6.316245]?[dhd]?dhd_conf_get_disable_proptx?:?fw_proptx=1,?disable_proptx=-1 [0658][????6.380768]?[dhd]?dhd_conf_map_country_list?:?CN/38 [0658][????6.381222]?[dhd]?dhd_conf_set_country?:?set?country?CN,?revision?38 [0658][????6.385992]?[dhd]?dhd_conf_set_country?:?Country?code:?CN?(CN/38) [0658][??OK??]?Started?Network?Manager. [0658][??OK??]?Reached?target?Network. [0658]?????????Starting?Permit?User?Sessions... [0658]?????????Starting?OpenBSD?Secure?Shell?server... [0658][??OK??]?Started?Permit?User?Sessions. [0658]?????????Starting?Hold?until?boot?process?finishes?up... [0658][??OK??]?Started?Hold?until?boot?process?finishes?up. [0658][??OK??]?Started?Serial?Getty?on?ttyFIQ0. [0658]?????????Starting?Set?console?scheme... [0658][??OK??]?Started?Set?console?scheme. [0658][??OK??]?Created?slice?system-getty.slice. [0658][??OK??]?Started?Getty?on?tty1. [0658][??OK??]?Reached?target?Login?Prompts. [0658][??OK??]?Started?OpenBSD?Secure?Shell?server. [0658][??OK??]?Started?Adbd?for?linux. [0658][??OK??]?Started?Setup?rockchip?platform?environment. [0658]?????????Starting?Light?Display?Manager... [0658][??OK??]?Reached?target?Multi-User?System. [0659][??OK??]?Started?Light?Display?Manager. [0659][??OK??]?Reached?target?Graphical?Interface. [0659]?????????Starting?Update?UTMP?about?System?Runlevel?Changes... [0659][??OK??]?Started?Update?UTMP?about?System?Runlevel?Changes. [0659] [0659]Ubuntu?18.04.6?LTS?firefly?ttyFIQ0?? [0639]root@firefly:~#?ls?-al?/proc/vmcore? [0641]-r--------?1?root?root?3885387776?Mar??5?22:49?/proc/vmcore [0624]root@firefly:~#?ls?-al?--block-size=m???/proc/vmcore?
系統正常啟動后,就可以將/proc/vmcore文件拷貝出來在ubuntu上用crash工具分析。
常見問題及解決辦法
在ARM平臺上,系統崩潰后卡死,未啟動第二內核
不清楚是宿主機的原因還是代碼原因,目前主線的 Linux kernel 代碼在執行命令使第一個內核崩潰之后,跳轉到第二個內核的過程中卡死,在社區上也有其他人遇到了類似的情況并給出了補丁,但是并沒有合并到主線,不過目前為了演示暫時不考慮為何原因導致這個問題的出現,如果你的 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 內核,需要更新到 7.2.5 版本才可以。
沒有生產vmcore
按照kdump執行流程,確定問題來自那個階段。
預留內存失敗
預留內存過大,設備沒有足夠的可用內存。默認會在0~4G預留內存。比如預留512M的空間,而在0~4G并沒有可用的512M空間,就會導致預留失敗。
加載內核失敗
是否預留內存,crashkernel是否配置?
預留內存失敗。
預留內存成功:嘗試使用kexec -d -p 查看失敗的具體原因。
第二內核啟動失敗
打印出bye后沒有任何信息輸出,可能是第二內核可能未配置串口,earlycon/console
oom后卡死,可能是預留內存太小。
驅動初始化失敗。有些驅動,比如dma32,可能只能使用0~4G內存,在4G以上預留內存會導致驅動加載失敗。
makedumpfile失敗
加上-D,打印出debug選項,查看失敗原因。
用戶態工具問題
kernel,kexec,makedumpfile,crash匹配問題,更新到最新的工具。
編輯:黃飛
評論
查看更多