By Toradex胡珊逢
對于嵌入式設(shè)備,盡管在部署前會經(jīng)歷大量的測試和驗證,但在使用現(xiàn)場有時候仍不可避免會出現(xiàn)意外情況,如Kernel opps、panic。當(dāng)出現(xiàn)類似情況時,系統(tǒng)日志往往無法及時寫入flash,重啟后不能獲得用于分析問題的關(guān)鍵信息。Ramoops可以應(yīng)對此類問題。當(dāng)發(fā)發(fā)生Kernel opps、panic時,它能夠?qū)⑾嚓P(guān)日志保存到特定的內(nèi)存區(qū)域,并在軟重啟后仍可以讀取。文章將使用安裝Linux BSP v3.0的Apalis iMX6計算機模塊進行說明。
首先使用Toradex Easy Installer安裝Linux BSP v3.0。然后下載對應(yīng)的Linux源碼,分支為toradex_4.14-2.3.x-imx。交叉編譯工具是gcc-arm-8.2-2019.01-x86_64-arm-linux-gnueabihf。
應(yīng)用Apalis iMX6默認內(nèi)核配置。
-----------------------------------------
$make apalis_imx6_defconfig
-----------------------------------------
開啟ramoops功能。
-----------------------------------------
$make menuconfig
File systems → Miscellaneous filesystems
Choose compression algorithm (ZLIB) --->
[*] Log kernel console messages
[*] Log user space messages
<*> Log panic/oops to a RAM buffer
-----------------------------------------
為了便于觸發(fā)kernel panic開啟sysrq功能。
-----------------------------------------
Kernel hacking
[*] Magic SysRq key
0x1) Enable magic SysRq key functions by default
[*] Enable magic SysRq key over serial
-----------------------------------------
最后重新編譯內(nèi)核以及內(nèi)核模塊。
-----------------------------------------
$ make zImage LOADADDR=10008000
$ make modules
-----------------------------------------
使用新的內(nèi)核和模塊重新啟動Apalis iMX6。Ramoops在內(nèi)核配置里又稱為PSTORE,使用下面命令查看之前的內(nèi)核內(nèi)置是否生效。
-----------------------------------------
root@apalis-imx6:~# zcat /proc/config.gz |grep PSTORE
CONFIG_PSTORE=y
CONFIG_PSTORE_ZLIB_COMPRESS=y
# CONFIG_PSTORE_LZO_COMPRESS is not set
# CONFIG_PSTORE_LZ4_COMPRESS is not set
CONFIG_PSTORE_CONSOLE=y
CONFIG_PSTORE_PMSG=y
CONFIG_PSTORE_RAM=y
root@apalis-imx6:~# zcat /proc/config.gz |grep SYSRQ
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
CONFIG_MAGIC_SYSRQ_SERIAL=y
-----------------------------------------
此時,ramoops還沒有配置完成,需要在device tree里創(chuàng)建對應(yīng)的節(jié)點。在這之前先確定在內(nèi)存中可以為ramoops預(yù)留的地址空間。在Linux運行下面命令。
-----------------------------------------
root@apalis-imx6:~# cat /proc/iomem
00100000-00103fff : /soc/caam-sm@00100000
00120000-00128fff : 120000.hdmi_core
00130000-00133fff : galcore register region
……
02204000-02207fff : galcore register region
02400000-027fffff : 2400000.ipu
02800000-02bfffff : 2800000.ipu
10000000-4fffffff : System RAM
10008000-10cfffff : Kernel code
10e00000-10eeb3cf : Kernel data
-----------------------------------------
RAM的物理地址空間為0x10000000-0x4fffffff,選擇在Kernel code和Kernel data之外的0x30000000作為ramoops的起始地址,大小為1MB。
在arch/arm/boot/dts/imx6q.dtsi的reserved-memory 節(jié)點里添加ramoops。
重新編譯device tree。
-----------------------------------------
$make imx6q-apalis-eval.dtb
-----------------------------------------
使用新的device tree啟動后,可以看到以下信息。
-----------------------------------------
root@apalis-imx6:~# dmesg|grep ramoops
[ 0.071682] pstore: Registered ramoops as persistent store backend
[ 0.071707] ramoops: attached 0x100000@0x30000000, ecc: 0/0
-----------------------------------------
下面命令分別設(shè)置系統(tǒng)在發(fā)生kernel panic時1秒后自動重啟,以及觸發(fā)kernel panic。
-----------------------------------------
root@apalis-imx6:~# echo 1 > /proc/sys/kernel/panic
root@apalis-imx6:~# echo c > /proc/sysrq-trigger
-----------------------------------------
在自動重啟后,將ramoops掛載到/home/root/pstore目錄,可以看到上次發(fā)生kerne panic時的日志。
-----------------------------------------
root@apalis-imx6:~# mkdir -p /home/root/pstore
root@apalis-imx6:~# mount -t pstore psotre /home/root/pstore
root@apalis-imx6:~# ls pstore/
console-ramoops-0 dmesg-ramoops-0 dmesg-ramoops-1
root@apalis-imx6:~/pstore# tail -n 5 console-ramoops-0
[ 856.337055] ffa0: 00be5898 00000000 00000020 76ed4bb4
[ 856.345259] ffc0: 00be5898 00000020 00000002 00000001 76ed71c0 00be6828 00000001 7ed702e0
[ 856.353460] ffe0: 00000000 7ed70138 76dd382d 76d88cd0 000f0010 ffffffff
[ 856.360101] r9:00be6828 r8:10c5387d r7:10c5387d r6:ffffffff r5:000f0010 r4:76d88cd0
[ 856.385215] Rebooting in 1 seconds..
root@apalis-imx6:~/pstore# tail -n 5 dmesg-ramoops-0
<4>[ 856.200454] r9:00000000 r8:00000000 r7:00000002 r6:00d00440 r5:a909bf00 r4:a909bf00
<4>[ 856.208233] [<80227be8>] (SyS_write) from [<80107d20>] (ret_fast_syscall+0x0/0x54)
<4>[ 856.215828] r9:a975a000 r8:80107f24 r7:00000004 r6:76f5bda0 r5:00d00440 r4:0000006c
<0>[ 856.223594] Code: e5834000 f57ff04e ebf07aaa e3a03000 (e5c34000)
<4>[ 856.229847] ---[ end trace 583cc693cbfd2cb1 ]---
-----------------------------------------
由于ramoops是將日志保存在內(nèi)存里,如果模塊是冷啟動,即電源復(fù)位,那么相關(guān)的內(nèi)容也不再保留。
-----------------------------------------
root@apalis-imx6:~# mount -t pstore psotre /home/root/pstore
root@apalis-imx6:~# ls pstore/
root@apalis-imx6:~#
-----------------------------------------
參考
https://git.toradex.cn/cgit/linux-toradex.git/tree/Documentation/admin-guide/ramoops.rst?h=toradex_4.14-2.3.x-imx
https://lwn.net/Articles/501748/
總結(jié)
ramoops可以使用較小的開銷記錄系統(tǒng)日志一般難以保存的kernel panic錯誤。由于存儲于內(nèi)存里面,因此在掉電后這些信息就不復(fù)存在。在Linux中還有許多其他的調(diào)試方法,如kdb, kdump, tracing等,它們的使用特點和復(fù)雜程度也各有不同,用戶可以根據(jù)需求加以選擇。
審核編輯:黃飛
-
Linux
+關(guān)注
關(guān)注
87文章
11215瀏覽量
208740 -
計算機
+關(guān)注
關(guān)注
19文章
7383瀏覽量
87641 -
內(nèi)存
+關(guān)注
關(guān)注
8文章
2982瀏覽量
73826 -
嵌入式設(shè)備
+關(guān)注
關(guān)注
0文章
110瀏覽量
16925
發(fā)布評論請先 登錄
相關(guān)推薦
評論