簡介
在內存發生panic時,須要把panic的日誌保存下來。以方便往後進行分析。
目前有三種記錄的方式: kdump; mtdoops; crashlog
你們對kdump比較瞭解。它主要使用於x86系統。由於它使用佔用大量內存和硬盤。
mtdoops和crashlog主要用於嵌入式的環境。也只是記錄文本日誌。
mtdoop功能在發生oops時,把msg區寫入特定的mt分區。寫入過程,不支持文件系統。直接二進制文本寫。它須要由mtd驅動的支持,就是mtd驅動支持mtd_panic_write。也就是原子式寫入。不能被中斷。通常flash不支持。
crashlog功能在發生oops時,把msg寫入以前分配好的mem區。並加上magic。重啓後,判斷有magic後,把上次的日誌放到/sys/kernel/debug/crashlog.
由於在發生oops,是把日誌寫入內存區,這個很容易保存是原子操做。但它不在標準內核中,它是openwrt裏有patch。由於不一樣的架構,對於在上電來保存一塊內存的方式也不太同樣。要使用它時,須要程序員增長几行代碼給這個功能事先分配一個物理地址固定(明確)的內存區。而且這個區域在熱重啓時,不被uboot等使用。
mtdoops
指定寫入哪一個分區(分區名或是分區號),可寫入的size。
使用此函數 kmsg_dump_register註冊一個回調函數,當發生OOPS時,回調一下cxt->dump.dump。
cxt->dump.dump函數則把讀取kmsg區的內容,直接調用mtd->write的驅動進行寫操做。
carshlog
在內核中有一個叫crashlog的東東,它完成以下操做
操做以下
1.在linux內核啓動時,保留一64K內存。用於記錄panic日誌。
2.使用kmsg_dump_register,註冊一個回調函數,當發生panic,oops時,把日誌記到保留內存。
3.linux內核上電後,把保留內存的內容寫入文件。 它是輸出在/sys/kernel/debug/crashlog中。
kmsg_dump機制
以上兩種方案都使用到了kmsg_dump的註冊機制。
註冊很簡單,就是把一個全局變量結構掛到一個全局list中。
kmsg_dump是oops時進入kmsg_dump的入口。由panic,die,oops_exit等函數調用。它會一一調用回調函數。
每個回調函數都會用到kmsg_dump_get_buffer。我沒有看懂這個函數,從註釋來看,它先是計算dump還有多少空間,而後把kmsg中最後的一部分寫進去。
ref: http://blog.csdn.net/wbd880419/article/details/70241130