ac8257 android 9 SYSTEM_LAST_KMSG
问题
记录的SYSTEM_LAST_KMSG被截断不全。只保存了64k左右。
log
kernel
I [ 0.000000]-(0)[0:swapper][memblock]mediatek,pstore: 0x47c90000 - 0x47d70000 (0xe0000)
I [ 0.000000]-(0)[0:swapper]OF: reserved mem: initialized node pstore-reserved-memor@47c90000, compatible id mediatek,pstore
I [ 0.130248].(0)[1:swapper/0]ramoops: pstore:address is 0x47c90000, size is 0xe0000, console_size is 0x40000, pmsg_size is 0x10000
I [ 0.132807].(0)[1:swapper/0]pstore: using zlib compression
I [ 0.133355].(0)[1:swapper/0]: console [pstore-1] enabled
I [ 0.133448].(0)[1:swapper/0]pstore: Registered ramoops as persistent store backend
system
640 1881 I BootReceiver: Copying /proc/last_kmsg to DropBox (SYSTEM_LAST_KMSG)
dropbox
# zcat /data/system/dropbox/SYSTEM_LAST_KMSG@1758006200998.txt.gz
isPrevious: true
Build: alps/full_ac8257_demo_1g_32/ac8257_demo_1g_32:9/PPR1.180610.011/42:user/test-keys
Hardware: ac8257_demo_1g_32
Revision: 0
Bootloader: unknown
Radio:
Kernel: Linux version 4.9.117+[[TRUNCATED]]
vateNetwork:(RSN INFO) [wlan index]=4 OwnMac=0a:00:a1:3f:41:72 BSSID=00:00:00:00:00:00 BMCIndex = 0 NetType=1
[ 63.138900] (3)[435:mtk_wmtd_worker][wlan][435]nicDeactivateNetwork:(RSN INFO) [wlan index]=4 OwnMac=0a:00:a1:3f:41:72 BSSID=00:00:00:00:00:00 BMCIndex = 255 NetType=1
[ 63.138914] (3)[435:mtk_wmtd_worker][wlan][435]p2pRoleFsmUninit:(P2P INFO) ->p2pRoleFsmUninit()
BootReceiver
frameworks/base/core/java/com/android/server/BootReceiver.java
logBootEvents
153 private String getPreviousBootHeaders() {
154 try {
155 return FileUtils.readTextFile(lastHeaderFile, 0, null);
156 } catch (IOException e) {
157 return null;
158 }
159 }
160
161 private String getCurrentBootHeaders() throws IOException {
162 return new StringBuilder(512)
163 .append("Build: ").append(Build.FINGERPRINT).append("\n")
164 .append("Hardware: ").append(Build.BOARD).append("\n")
165 .append("Revision: ")
166 .append(SystemProperties.get("ro.revision", "")).append("\n")
167 .append("Bootloader: ").append(Build.BOOTLOADER).append("\n")
168 .append("Radio: ").append(Build.getRadioVersion()).append("\n")
169 .append("Kernel: ")
170 .append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"))
171 .append("\n").toString();
172 }
173
174
175 private String getBootHeadersToLogAndUpdate() throws IOException {
176 final String oldHeaders = getPreviousBootHeaders();
177 final String newHeaders = getCurrentBootHeaders();
178
179 try {
180 FileUtils.stringToFile(lastHeaderFile, newHeaders);
181 } catch (IOException e) {
182 Slog.e(TAG, "Error writing " + lastHeaderFile, e);
183 }
184
185 if (oldHeaders == null) {
186 // If we failed to read the old headers, use the current headers
187 // but note this in the headers so we know
188 return "isPrevious: false\n" + newHeaders;
189 }
190
191 return "isPrevious: true\n" + oldHeaders;
192 }
193
194 private void logBootEvents(Context ctx) throws IOException {
195 final DropBoxManager db = (DropBoxManager) ctx.getSystemService(Context.DROPBOX_SERVICE);
196 final String headers = getBootHeadersToLogAndUpdate();
197 final String bootReason = SystemProperties.get("ro.boot.bootreason", null);
198
199 String recovery = RecoverySystem.handleAftermath(ctx);
200 if (recovery != null && db != null) {
201 db.addText("SYSTEM_RECOVERY_LOG", headers + recovery);
202 }
203
204 String lastKmsgFooter = "";
205 if (bootReason != null) {
206 lastKmsgFooter = new StringBuilder(512)
207 .append("\n")
208 .append("Boot info:\n")
209 .append("Last boot reason: ").append(bootReason).append("\n")
210 .toString();
211 }
212
213 HashMap<String, Long> timestamps = readTimestamps();
214
215 if (SystemProperties.getLong("ro.runtime.firstboot", 0) == 0) {
216 if (StorageManager.inCryptKeeperBounce()) {
217 // Encrypted, first boot to get PIN/pattern/password so data is tmpfs
218 // Don't set ro.runtime.firstboot so that we will do this again
219 // when data is properly mounted
220 } else {
221 String now = Long.toString(System.currentTimeMillis());
222 SystemProperties.set("ro.runtime.firstboot", now);
223 }
224 if (db != null) db.addText("SYSTEM_BOOT", headers);
225
226 // Negative sizes mean to take the *tail* of the file (see FileUtils.readTextFile())
227 addFileWithFootersToDropBox(db, timestamps, headers, lastKmsgFooter,
228 "/proc/last_kmsg", -LOG_SIZE, "SYSTEM_LAST_KMSG");
229 addFileWithFootersToDropBox(db, timestamps, headers, lastKmsgFooter,
230 "/sys/fs/pstore/console-ramoops", -LOG_SIZE, "SYSTEM_LAST_KMSG");
231 addFileWithFootersToDropBox(db, timestamps, headers, lastKmsgFooter,
232 "/sys/fs/pstore/console-ramoops-0", -LOG_SIZE, "SYSTEM_LAST_KMSG");
233 addFileToDropBox(db, timestamps, headers, "/cache/recovery/log", -LOG_SIZE,
234 "SYSTEM_RECOVERY_LOG");
235 addFileToDropBox(db, timestamps, headers, "/cache/recovery/last_kmsg",
236 -LOG_SIZE, "SYSTEM_RECOVERY_KMSG");
237 addAuditErrorsToDropBox(db, timestamps, headers, -LOG_SIZE, "SYSTEM_AUDIT");
238 } else {
239 if (db != null) db.addText("SYSTEM_RESTART", headers);
240 }
addFileWithFootersToDropBox
287 private static void addFileWithFootersToDropBox(
288 DropBoxManager db, HashMap<String, Long> timestamps,
289 String headers, String footers, String filename, int maxSize,
290 String tag) throws IOException {
291 if (db == null || !db.isTagEnabled(tag)) return; // Logging disabled
292
293 File file = new File(filename);
294 long fileTime = file.lastModified();
295 if (fileTime <= 0) return; // File does not exist
296
297 if (timestamps.containsKey(filename) && timestamps.get(filename) == fileTime) {
298 return; // Already logged this particular file
299 }
300
301 timestamps.put(filename, fileTime);
302
303
304 String fileContents = FileUtils.readTextFile(file, maxSize, "[[TRUNCATED]]\n");
305 String text = headers + fileContents + footers;
306 // Create an additional report for system server native crashes, with a special tag.
307 if (tag.equals(TAG_TOMBSTONE) && fileContents.contains(">>> system_server <<<")) {
308 addTextToDropBox(db, "system_server_native_crash", text, filename, maxSize);
309 }
310 addTextToDropBox(db, tag, text, filename, maxSize);
311 }
LOG_SIZE
调试版本96K,其他64K。
62 /**63 * Performs a number of miscellaneous, non-system-critical actions64 * after the system has finished booting.65 */66 public class BootReceiver extends BroadcastReceiver {67 private static final String TAG = "BootReceiver";6869 // Maximum size of a logged event (files get truncated if they're longer).70 // Give userdebug builds a larger max to capture extra debug, esp. for last_kmsg.71 private static final int LOG_SIZE =72 SystemProperties.getInt("ro.debuggable", 0) == 1 ? 98304 : 65536;
isTagEnabled
frameworks/base/core/java/android/os/DropBoxManager.java
frameworks/base/services/core/java/com/android/server/DropBoxManagerService.java
patch
修改LOG_SIZE为256k,保存完整的last_kmsg。
--- a/core/java/com/android/server/BootReceiver.java
+++ b/core/java/com/android/server/BootReceiver.java
@@ -69,7 +69,7 @@ public class BootReceiver extends BroadcastReceiver {// Maximum size of a logged event (files get truncated if they're longer).// Give userdebug builds a larger max to capture extra debug, esp. for last_kmsg.private static final int LOG_SIZE =
- SystemProperties.getInt("ro.debuggable", 0) == 1 ? 98304 : 65536;
+ SystemProperties.getInt("ro.debuggable", 0) == 1 ? 98304 : 0x40000;private static final File TOMBSTONE_DIR = new File("/data/tombstones");private static final String TAG_TOMBSTONE = "SYSTEM_TOMBSTONE";
kernel-4.9
.config
RAM_CONSOLE
CONFIG_MTK_RAM_CONSOLE=y
CONFIG_MTK_RAM_CONSOLE_USING_SRAM=y
# CONFIG_MTK_RAM_CONSOLE_USING_DRAM is not set
CONFIG_MTK_RAM_CONSOLE_SIZE=0x800
CONFIG_MTK_RAM_CONSOLE_ADDR=0x0010DC00
CONFIG_MTK_RAM_CONSOLE_DRAM_SIZE=0x10000
CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR=0x47C80000
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
CONFIG_PSTORE_CONSOLE_SIZE=0x40000
CONFIG_PSTORE_PMSG_SIZE=0x10000
CONFIG_PSTORE_MEM_ADDR=0x47C90000
CONFIG_PSTORE_MEM_SIZE=0xe0000
last_kmsg
drivers/misc/mediatek/ram_console/mtk_ram_console.c
ram_console_late_init(*)
730 static int ram_console_file_open(struct inode *inode, struct file *file)731 {732 return single_open(file, ram_console_show, inode->i_private);733 }734735 static const struct file_operations ram_console_file_ops = {736 .owner = THIS_MODULE,737 .open = ram_console_file_open,738 .read = seq_read,739 .llseek = seq_lseek,740 .release = single_release,741 };742743 static int __init ram_console_late_init(void)744 {745 struct proc_dir_entry *entry;746747 if (reserve_mem_fail) {748 pr_info("ram_console/pstore wrong reserved memory\n");749 BUG();750 }751 entry = proc_create("last_kmsg", 0444, NULL, &ram_console_file_ops);752 if (!entry) {753 pr_err("ram_console: failed to create proc entry\n");754 kfree(ram_console_old);755 ram_console_old = NULL;756 return 0;757 }758 return 0;759 }
ram_console_show(*)
724 static int ram_console_show(struct seq_file *m, void *v)725 {726 ram_console_lastk_show(ram_console_old, m, v);727 return 0;728 }
ram_console_lastk_show(*)
475 static int ram_console_lastk_show(struct ram_console_buffer *buffer,476 struct seq_file *m, void *v)477 {478 unsigned int wdt_status;479480 if (!buffer) {481 pr_notice("ram_console: buffer is null\n");482 seq_puts(m, "buffer is null.\n");483 return 0;484 }485486 if (ram_console_check_header(buffer) && buffer->sz_buffer != 0) {487 pr_notice("ram_console: buffer %p, size %x(%x)\n",488 buffer, buffer->sz_buffer,489 ram_console_buffer->sz_buffer);490 seq_write(m, buffer, ram_console_buffer->sz_buffer);491 return 0;492 }493 if (buffer->off_pl == 0 || buffer->off_pl + ALIGN(buffer->sz_pl, 64)494 != buffer->off_lpl) {495 /* workaround for compatibility to old preloader & lk (OTA) */496 wdt_status = *((unsigned char *)buffer + 12);497 } else498 wdt_status = LAST_RRPL_BUF_VAL(buffer, wdt_status);499500 seq_printf(m, "ram console header, hw_status: %u, fiq step %u.\n",501 wdt_status, LAST_RRR_BUF_VAL(buffer, fiq_step));502 seq_printf(m, "%s, old status is %u.\n",503 ram_console_clear ?504 "Clear" : "Not Clear", old_wdt_status);505506 #ifdef CONFIG_PSTORE_CONSOLE507 pstore_console_show(PSTORE_TYPE_CONSOLE, m, v);508 #else509 if (buffer->off_console != 0510 && buffer->off_linux + ALIGN(sizeof(struct last_reboot_reason),511 64) == buffer->off_console512 && buffer->sz_console == buffer->sz_buffer - buffer->off_console513 && buffer->log_size <= buffer->sz_console514 && buffer->log_start <= buffer->sz_console) {515 seq_write(m, (void *)buffer + buffer->off_console +516 buffer->log_start,517 buffer->log_size - buffer->log_start);518 seq_write(m, (void *)buffer + buffer->off_console,519 buffer->log_start);520 } else {521 seq_puts(m,522 "header may be corrupted, dump the raw buffer for reference only\n");523 seq_write(m, buffer, ram_console_buffer->sz_buffer);524 }525 #endif526 return 0;527 }
pstore_console_show(*)
306 void pstore_console_show(enum pstore_type_id type_id, struct seq_file *m,307 void *v)308 {309 struct pstore_info *psi = psinfo;310 char *buf = NULL;311 ssize_t size;312 u64 id;313 int count;314 enum pstore_type_id type;315 struct timespec time;316 bool compressed;317 ssize_t ecc_notice_size = 0;318319 if (!psi)320 return;321 mutex_lock(&psi->read_mutex);322 if (psi->open && psi->open(psi))323 goto out;324325 while ((size = psi->read(&id, &type, &count, &time, &buf, &compressed,326 &ecc_notice_size, psi)) > 0) {327 if (type == type_id)328 seq_write(m, buf, size);329 kfree(buf);330 buf = NULL;331 }332333 if (psi->close)334 psi->close(psi);335 out:336 mutex_unlock(&psi->read_mutex);337 }
fs/pstore/ram.c
ramoops_pstore_read(**)
读取上一次日志。
202 static bool prz_ok(struct persistent_ram_zone *prz)
203 {
204 return !!prz && !!(persistent_ram_old_size(prz) +
205 persistent_ram_ecc_string(prz, NULL, 0));
206 }
207
208 static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
209 int *count, struct timespec *time,
210 char **buf, bool *compressed,
211 ssize_t *ecc_notice_size,
212 struct pstore_info *psi)
213 {
214 ssize_t size;
215 struct ramoops_context *cxt = psi->data;
216 struct persistent_ram_zone *prz = NULL;
217 int header_length = 0;
218
219 /* Ramoops headers provide time stamps for PSTORE_TYPE_DMESG, but
220 * PSTORE_TYPE_CONSOLE and PSTORE_TYPE_FTRACE don't currently have
221 * valid time stamps, so it is initialized to zero.
222 */
223 time->tv_sec = 0;
224 time->tv_nsec = 0;
225 *compressed = false;
226
227 /* Find the next valid persistent_ram_zone for DMESG */
228 while (cxt->dump_read_cnt < cxt->max_dump_cnt && !prz) {
229 prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt,
230 cxt->max_dump_cnt, id, type,
231 PSTORE_TYPE_DMESG, 1);
232 if (!prz_ok(prz))
233 continue;
234 header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz),
235 time, compressed);
236 /* Clear and skip this DMESG record if it has no valid header */
237 if (!header_length) {
238 persistent_ram_free_old(prz);
239 persistent_ram_zap(prz);
240 prz = NULL;
241 }
242 }
243
244 if (!prz_ok(prz))
245 prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
246 1, id, type, PSTORE_TYPE_CONSOLE, 0);
247 if (!prz_ok(prz)) {
248 prz = ramoops_get_next_prz(&cxt->bprz, &cxt->bconsole_read_cnt,
249 1, id, type, PSTORE_TYPE_CONSOLE, 0);
250 *id = 2;
251 }
252 if (!prz_ok(prz))
253 prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt,
254 1, id, type, PSTORE_TYPE_FTRACE, 0);
255 if (!prz_ok(prz))
256 prz = ramoops_get_next_prz(&cxt->mprz, &cxt->pmsg_read_cnt,
257 1, id, type, PSTORE_TYPE_PMSG, 0);
258 if (!prz_ok(prz))
259 return 0;
260
261 size = persistent_ram_old_size(prz) - header_length;
262
263 /* ECC correction notice */
264 *ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
265
266 *buf = kmalloc(size + *ecc_notice_size + 1, GFP_KERNEL);
267 if (*buf == NULL)
268 return -ENOMEM;
269
270 memcpy(*buf, (char *)persistent_ram_old(prz) + header_length, size);
271 persistent_ram_ecc_string(prz, *buf + size, *ecc_notice_size + 1);
272
273 return size;
274 }
ram_console_save_old
551 static int __init ram_console_save_old(struct ram_console_buffer *buffer,552 size_t buffer_size)553 {554 ram_console_old = kmalloc(buffer_size, GFP_KERNEL);555 if (ram_console_old == NULL) {556 pr_notice("ram_console: failed to allocate old buffer\n");557 return -1;558 }559 memcpy(ram_console_old, buffer, buffer_size);560 aee_rr_show_in_log();561 return 0;562 }
ram_console_init
CONFIG_PSTORE未定义时才注册ram_console控制台。否则fs/pstore/platform.c中注册pstore_console控制台。
564 static int __init ram_console_init(struct ram_console_buffer *buffer,565 size_t buffer_size)566 {567 ram_console_buffer = buffer;568 buffer->sz_buffer = buffer_size;569570 if (buffer->sig != REBOOT_REASON_SIG ||571 ram_console_check_header(buffer)) {572 memset_io((void *)buffer, 0, buffer_size);573 buffer->sig = REBOOT_REASON_SIG;574 ram_console_clear = 1;575 } else {576 old_wdt_status = LAST_RRPL_BUF_VAL(buffer, wdt_status);577 }578 ram_console_save_old(buffer, buffer_size);579 if (buffer->sz_lk != 0 && buffer->off_lk + ALIGN(buffer->sz_lk, 64) ==580 buffer->off_llk)581 buffer->off_linux = buffer->off_llk + ALIGN(buffer->sz_lk, 64);582 else583 /* OTA:leave enough space for pl/lk */584 buffer->off_linux = 512;585 buffer->sz_buffer = buffer_size;586 buffer->off_console = buffer->off_linux +587 ALIGN(sizeof(struct last_reboot_reason), 64);588 buffer->sz_console = buffer->sz_buffer - buffer->off_console;589 buffer->log_start = 0;590 buffer->log_size = 0;591 memset_io((void *)buffer + buffer->off_linux, 0,592 buffer_size - buffer->off_linux);593 ram_console_init_desc(buffer->off_linux);594 #ifndef CONFIG_PSTORE595 register_console(&ram_console);596 #endif597 ram_console_init_val();598 ram_console_init_done = 1;599 return 0;600 }
ram_console_write
429 void ram_console_write(struct console *console, const char *s,430 unsigned int count)431 {432 unsigned long flags;433434 if (atomic_read(&rc_in_fiq))435 return;436437 spin_lock_irqsave(&ram_console_lock, flags);438439 sram_log_save(s, count);440441 spin_unlock_irqrestore(&ram_console_lock, flags);442 }443444 static struct console ram_console = {445 .name = "ram",446 .write = ram_console_write,447 .flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME,448 .index = -1,449 };
ram_console_early_init
666 static int __init ram_console_early_init(void)667 {668 struct ram_console_buffer *bufp = NULL;669 size_t buffer_size = 0;670 #if defined(CONFIG_MTK_RAM_CONSOLE_USING_SRAM)671 #ifdef CONFIG_OF672 struct mem_desc_t sram = { 0 };673674 if (of_scan_flat_dt(dt_get_ram_console, &sram)) {675 if (sram.start == 0) {676 sram.start = CONFIG_MTK_RAM_CONSOLE_ADDR;677 sram.size = CONFIG_MTK_RAM_CONSOLE_SIZE;678 }679 bufp = ioremap_wc(sram.start, sram.size);680 ram_console_buffer_pa = (struct ram_console_buffer *)sram.start;681 if (bufp)682 buffer_size = sram.size;683 else {684 pr_err("ram_console: ioremap failed, [0x%lx, 0x%lx]\n",685 sram.start,686 sram.size);687 return 0;688 }689 } else {690 return 0;691 }692 #else693 bufp = ioremap_wc(CONFIG_MTK_RAM_CONSOLE_ADDR,694 CONFIG_MTK_RAM_CONSOLE_SIZE);695 if (bufp)696 buffer_size = CONFIG_MTK_RAM_CONSOLE_SIZE;697 ram_console_buffer_pa = CONFIG_MTK_RAM_CONSOLE_ADDR;698 else {699 pr_err("ram_console: ioremap failed, [0x%x, 0x%x]\n",700 sram.start, sram.size);701 return 0;702 }703 #endif704 #elif defined(CONFIG_MTK_RAM_CONSOLE_USING_DRAM)705 bufp = remap_lowmem(CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR,706 CONFIG_MTK_RAM_CONSOLE_DRAM_SIZE);707 ram_console_buffer_pa =708 (struct ram_console_buffer *)CONFIG_MTK_RAM_CONSOLE_DRAM_ADDR;709 if (bufp == NULL) {710 pr_err("ram_console: ioremap failed\n");711 return 0;712 }713 buffer_size = CONFIG_MTK_RAM_CONSOLE_DRAM_SIZE;714 #else715 return 0;716 #endif717718 pr_notice("ram_console: buffer start: 0x%p, size: 0x%zx\n",719 bufp, buffer_size);720 mtk_cpu_num = num_present_cpus();721 return ram_console_init(bufp, buffer_size);722 }
dt_get_ram_console
642 #if defined(CONFIG_MTK_RAM_CONSOLE_USING_SRAM)643 #ifdef CONFIG_OF644 static int __init dt_get_ram_console(unsigned long node, const char *uname,645 int depth, void *data)646 {647 struct mem_desc_t *sram;648649 if (depth != 1 || (strcmp(uname, "chosen") != 0650 && strcmp(uname, "chosen@0") != 0))651 return 0;652653 sram = (struct mem_desc_t *) of_get_flat_dt_prop(node,654 "ram_console", NULL);655 if (sram) {656 pr_notice("ram_console:[DT] 0x%lx@0x%lx\n",657 sram->size, sram->start);658 *(struct mem_desc_t *) data = *sram;659 }660661 return 1;662 }663 #endif664 #endif
dts
reserved-memory
38 / {39 model = "Autochips Inc. AC8257";40 compatible = "atc,ac8257", "atc,ac8257-emu";4142 reserved-memory {43 #address-cells = <2>;44 #size-cells = <2>;45 ranges;4647 ram_console-reserved-memor@47c80000 {48 compatible = "mediatek,ram_console";49 reg = <0x0 0x47c80000 0x0 0x10000>;50 };5152 pstore-reserved-memor@47c90000 {53 compatible = "mediatek,pstore";54 reg = <0x0 0x47c90000 0x0 0xE0000>;55 };
PSTORE
persistent_ram_zone | size | offset |
dump | 0x4f000 | 0x47c90000 |
cconsole | 0x40000 | 0x47cdf000 |
bconsole | 0x40000 | 0x47d1f000 |
ftrace | 0x01000 | 0x47d5f000 |
pmsg | 0x10000 | 0x47d60000 |
0xe0000 |
32 struct persistent_ram_buffer {33 uint32_t sig;34 atomic_t start;35 atomic_t size;36 uint8_t data[0];37 };46 #define PERSISTENT_RAM_SIG (0x43474244) /* DBGC */
PSTORE_TYPE
33 /* types */34 enum pstore_type_id {35 PSTORE_TYPE_DMESG = 0,36 PSTORE_TYPE_MCE = 1,37 PSTORE_TYPE_CONSOLE = 2,38 PSTORE_TYPE_FTRACE = 3,39 /* PPC64 partition types */40 PSTORE_TYPE_PPC_RTAS = 4,41 PSTORE_TYPE_PPC_OF = 5,42 PSTORE_TYPE_PPC_COMMON = 6,43 PSTORE_TYPE_PMSG = 7,44 PSTORE_TYPE_PPC_OPAL = 8,45 PSTORE_TYPE_UNKNOWN = 25546 };
PSTORE_CONSOLE
/sys/fs/pstore/console-ramoopsfs/pstore/ram.cramoops_initramoops_register_dummyramoops_proberamoops_init_przsramoops_init_przpstore_registerramoops_console_write_buframoops_pstore_readfs/pstore/platform.cpstore_registerregister_console
PSTORE_PMSG
/sys/fs/pstore/pmsg-ramoops-0
ramoops_probe(*)
648 pr_notice("pstore:address is 0x%lx, size is 0x%lx, console_size is 0x%zx, pmsg_size is 0x%zx\n",
649 (unsigned long)cxt->phys_addr, cxt->size,
650 cxt->console_size, cxt->pmsg_size);
651 paddr = cxt->phys_addr;
652
653 dump_mem_sz = cxt->size - cxt->console_size * 2 - cxt->ftrace_size
654 - cxt->pmsg_size;
655 err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz);
656 if (err)
657 goto fail_out;
658
659 err = ramoops_init_prz(dev, cxt, &cxt->cprz, &paddr,
660 cxt->console_size, 0);
661 if (err)
662 goto fail_init_cprz;
663
664 err = ramoops_init_prz(dev, cxt, &cxt->bprz, &paddr,
665 cxt->console_size, 0);
666 if (err)
667 goto fail_init_bprz;
668
669 err = ramoops_init_prz(dev, cxt, &cxt->fprz, &paddr, cxt->ftrace_size,
670 LINUX_VERSION_CODE);
671 if (err)
672 goto fail_init_fprz;
673
674 err = ramoops_init_prz(dev, cxt, &cxt->mprz, &paddr, cxt->pmsg_size, 0);
675 if (err)
676 goto fail_init_mprz;
sram_log_save
301 void sram_log_save(const char *msg, int count)302 {303 pstore_bconsole_write(NULL, msg, count);304 }
pstore_simp_console_write(*)
605 static void pstore_simp_console_write(struct console *con, const char *s,
606 unsigned int c)
607 {
608 u64 id;
609 bool compressed = false;
610
611 psinfo->write_buf(PSTORE_TYPE_CONSOLE, 0, &id, 0, s, compressed, c,
612 psinfo);
613 }
pstore_bconsole_write
fs/pstore/platform.c
615 void pstore_bconsole_write(struct console *con, const char *s, unsigned int c)
616 {
617 u64 id;
618 bool compressed = false;
619
620 if (psinfo)
621 psinfo->write_buf(PSTORE_TYPE_CONSOLE, 1, &id, 0, s, compressed,
622 c, psinfo);
623 }
ramoops_pstore_write_buf(*)
fs/pstore/ram.c
reason 0写cprz, reason 1写bprz(last_kmsg)。
299 static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
300 enum kmsg_dump_reason reason,
301 u64 *id, unsigned int part,
302 const char *buf,
303 bool compressed, size_t size,
304 struct pstore_info *psi)
305 {
306 struct ramoops_context *cxt = psi->data;
307 struct persistent_ram_zone *prz;
308 size_t hlen;
309
310 if (type == PSTORE_TYPE_CONSOLE) {
311 if (reason == 0) {
312 if (!cxt->cprz)
313 return -ENOMEM;
314 persistent_ram_write(cxt->cprz, buf, size);
315 } else {
316 if (!cxt->bprz)
317 return -ENOMEM;
318 persistent_ram_write(cxt->bprz, buf, size);
319 }
320 return 0;
321 } else if (type == PSTORE_TYPE_FTRACE) {
322 if (!cxt->fprz)
323 return -ENOMEM;
324 persistent_ram_write(cxt->fprz, buf, size);
325 return 0;
326 } else if (type == PSTORE_TYPE_PMSG) {
327 if (!cxt->mprz)
328 return -ENOMEM;
329 persistent_ram_write(cxt->mprz, buf, size);
330 return 0;
331 }
332
333 if (type != PSTORE_TYPE_DMESG)
334 return -EINVAL;
335
336 /* Out of the various dmesg dump types, ramoops is currently designed
337 * to only store crash logs, rather than storing general kernel logs.
338 */
339 if (reason != KMSG_DUMP_OOPS &&
340 reason != KMSG_DUMP_PANIC)
341 return -EINVAL;
342
343 /* Skip Oopes when configured to do so. */
344 if (reason == KMSG_DUMP_OOPS && !cxt->dump_oops)
345 return -EINVAL;
346
347 /* Explicitly only take the first part of any new crash.
348 * If our buffer is larger than kmsg_bytes, this can never happen,
349 * and if our buffer is smaller than kmsg_bytes, we don't want the
350 * report split across multiple records.
351 */
352 if (part != 1)
353 return -ENOSPC;
354
355 if (!cxt->przs)
356 return -ENOSPC;
357
358 prz = cxt->przs[cxt->dump_write_cnt];
359
360 hlen = ramoops_write_kmsg_hdr(prz, compressed);
361 if (size + hlen > prz->buffer_size)
362 size = prz->buffer_size - hlen;
363 persistent_ram_write(prz, buf, size);
364
365 cxt->dump_write_cnt = (cxt->dump_write_cnt + 1) % cxt->max_dump_cnt;
366
367 return 0;
368 }
persistent_ram_write(*)
ramoops_init_prz(*)
496 static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt,
497 struct persistent_ram_zone **prz,
498 phys_addr_t *paddr, size_t sz, u32 sig)
499 {
500 if (!sz)
501 return 0;
502
503 if (*paddr + sz - cxt->phys_addr > cxt->size) {
504 dev_err(dev, "no room for mem region (0x%zx@0x%llx) in (0x%lx@0x%llx)\n",
505 sz, (unsigned long long)*paddr,
506 cxt->size, (unsigned long long)cxt->phys_addr);
507 return -ENOMEM;
508 }
509
510 *prz = persistent_ram_new(*paddr, sz, sig, &cxt->ecc_info,
511 cxt->memtype, 0);
512 if (IS_ERR(*prz)) {
513 int err = PTR_ERR(*prz);
514
515 dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
516 sz, (unsigned long long)*paddr, err);
517 return err;
518 }
519
520 persistent_ram_zap(*prz);
521
522 *paddr += sz;
523
524 return 0;
525 }
persistent_ram_new(*)
528 struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size,
529 u32 sig, struct persistent_ram_ecc_info *ecc_info,
530 unsigned int memtype, u32 flags)
531 {
532 struct persistent_ram_zone *prz;
533 int ret = -ENOMEM;
534
535 prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL);
536 if (!prz) {
537 pr_err("failed to allocate persistent ram zone\n");
538 goto err;
539 }
540
541 /* Initialize general buffer state. */
542 raw_spin_lock_init(&prz->buffer_lock);
543 prz->flags = flags;
544
545 ret = persistent_ram_buffer_map(start, size, prz, memtype);
546 if (ret)
547 goto err;
548
549 ret = persistent_ram_post_init(prz, sig, ecc_info);
550 if (ret)
551 goto err;
552
553 return prz;
554 err:
555 persistent_ram_free(prz);
556 return ERR_PTR(ret);
557 }
persistent_ram_buffer_map(*)
453 static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size,
454 struct persistent_ram_zone *prz, int memtype)
455 {
456 prz->paddr = start;
457 prz->size = size;
458
459 if (pfn_valid(start >> PAGE_SHIFT))
460 prz->vaddr = persistent_ram_vmap(start, size, memtype);
461 else
462 prz->vaddr = persistent_ram_iomap(start, size, memtype);
463
464 if (!prz->vaddr) {
465 pr_err("%s: Failed to map 0x%llx pages at 0x%llx\n", __func__,
466 (unsigned long long)size, (unsigned long long)start);
467 return -ENOMEM;
468 }
469
470 prz->buffer = prz->vaddr + offset_in_page(start);
471 prz->buffer_size = size - sizeof(struct persistent_ram_buffer);
472
473 return 0;
474 }
fs/pstore/ram_core.c
persistent_ram_post_init(*)
persistent_ram_save_old保存上一次日志。
476 static int persistent_ram_post_init(struct persistent_ram_zone *prz, u32 sig,
477 struct persistent_ram_ecc_info *ecc_info)
478 {
479 int ret;
480
481 ret = persistent_ram_init_ecc(prz, ecc_info);
482 if (ret)
483 return ret;
484
485 sig ^= PERSISTENT_RAM_SIG;
486
487 if (prz->buffer->sig == sig) {
488 if (buffer_size(prz) > prz->buffer_size ||
489 buffer_start(prz) > buffer_size(prz))
490 pr_info("found existing invalid buffer, size %zu, start %zu\n",
491 buffer_size(prz), buffer_start(prz));
492 else {
493 pr_debug("found existing buffer, size %zu, start %zu\n",
494 buffer_size(prz), buffer_start(prz));
495 persistent_ram_save_old(prz);
496 return 0;
497 }
498 } else {
499 pr_debug("no valid data in buffer (sig = 0x%08x)\n",
500 prz->buffer->sig);
501 }
502
503 /* Rewind missing or invalid memory area. */
504 prz->buffer->sig = sig;
505 persistent_ram_zap(prz);
506
507 return 0;
508 }
ramoops_get_next_prz
persistent_ram_save_old(**)
struct persistent_ram_zone
44 struct persistent_ram_zone {45 phys_addr_t paddr;46 size_t size;47 void *vaddr;48 struct persistent_ram_buffer *buffer;49 size_t buffer_size;50 u32 flags;51 raw_spinlock_t buffer_lock;5253 /* ECC correction */54 char *par_buffer;55 char *par_header;56 struct rs_control *rs_decoder;57 int corrected_bytes;58 int bad_blocks;59 struct persistent_ram_ecc_info ecc_info;6061 char *old_log;62 size_t old_log_size;63 };
/proc/last_kmsg
文件大小262206(0x4003E),256k62bytes = 256k-12+74。
74字节:
ram console header, hw_status: 2, fiq step 0.
Not Clear, old status is 2.
io
# echo -e "\x44\x42\x47\x43"
DBGC
dump
# io -l 256 0x47c90000
47c90000: 44 42 47 43 00 00 00 00 00 00 00 00 ff ff ff ff
47c90010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c90020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c90030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c90040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c90050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c90060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c90070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c90080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c90090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c900a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c900b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c900c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c900d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c900e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47c900f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
cconsole
# io -l 256 0x47cdf000
47cdf000: 44 42 47 43 e9 b2 00 00 f4 ff 03 00 30 30 30 5d
47cdf010: 2c 5b 30 78 31 35 30 34 34 44 30 43 20 30 30 30
47cdf020: 30 30 30 30 30 5d 0a 5b 35 37 38 35 38 2e 36 30
47cdf030: 30 33 35 35 5d 20 20 28 31 29 5b 32 32 35 35 31
47cdf040: 3a 50 72 6f 67 57 6f 72 6b 69 6e 67 31 43 68 33
47cdf050: 5d 5b 49 53 50 5d 5b 30 78 31 35 30 34 34 44 31
47cdf060: 30 20 30 30 30 30 43 30 30 30 5d 2c 5b 30 78 31
47cdf070: 35 30 34 34 44 31 34 20 30 30 30 30 30 30 30 30
47cdf080: 5d 2c 5b 30 78 31 35 30 34 34 44 31 38 20 30 30
47cdf090: 30 30 30 30 30 30 5d 2c 5b 30 78 31 35 30 34 34
47cdf0a0: 44 31 43 20 30 30 30 30 30 30 30 30 5d 0a 5b 35
47cdf0b0: 37 38 35 38 2e 36 30 30 33 36 36 5d 20 20 28 33
47cdf0c0: 29 5b 32 32 35 34 35 3a 50 72 6f 67 57 6f 72 6b
47cdf0d0: 69 6e 67 31 43 68 31 5d 5b 49 53 50 5d 5b 30 78
47cdf0e0: 31 35 30 34 34 44 31 30 20 30 30 30 30 43 30 30
47cdf0f0: 30 5d 2c 5b 30 78 31 35 30 34 34 44 31 34 20 30
bconsole
# io -l 256 0x47d1f000
47d1f000: 44 42 47 43 00 00 00 00 00 00 00 00 ff ff ff ff
47d1f010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f0a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f0b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f0c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f0d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f0e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d1f0f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ftrace
# /data/xbin/io -l 256 0x47d5f000
47d5f000: 31 4b 43 43 00 00 00 00 00 00 00 00 ff ff ff ff
47d5f010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f0a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f0b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f0c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f0d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f0e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d5f0f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
pmsg
# io -l 256 0x47d60000
47d60000: 44 42 47 43 00 00 00 00 00 00 00 00 ff ff ff ff
47d60010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d60020: ff ff ff ff ff bf ff ff ff 7e ff ff ff ff ff ff
47d60030: ff ff ff ff ff ff ff ff ff ff ff bf ff ff ff ff
47d60040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d60050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d60060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d60070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d60080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d60090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d600a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d600b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d600c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d600d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d600e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
47d600f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
px3 android 7.1.1
kernel
.config
# CONFIG_ANDROID_RAM_CONSOLE is not set
last_log
arch/arm/plat-rk/last_log.c
arch/arm/common/fiq_debugger.c
drivers/staging/android/ram_console.cram_console_module_initram_console_driver_proberam_console_initram_console_save_oldram_console_read_old