当前位置: 首页 > news >正文

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_zonesizeoffset
dump0x4f0000x47c90000
cconsole0x400000x47cdf000
bconsole0x400000x47d1f000
ftrace0x010000x47d5f000
pmsg0x100000x47d60000
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

http://www.dtcms.com/a/392275.html

相关文章:

  • ARM 架构与嵌入式系统
  • ARM(14) - LCD(1)清屏和画图形
  • Linux第十九讲:传输层协议UDP
  • 计算机网络学习(四、网络层)
  • 开启科学计算之旅:《MATLAB程序设计》课程导览
  • MATLAB | 数学模型 | 传染病 SIR 模型的参数确定
  • MATLAB基本运算(2)
  • 小红书数据分析面试题及参考答案
  • SpringCloudStream:消息驱动组件
  • ret2text-CTFHub技能树
  • VirtualBox 7 虚拟机的硬盘如何扩大?
  • React新闻发布系统 权限列表开发
  • 23种设计模式之【策略模式】-核心原理与 Java 实践
  • 前端实战从零构建响应式井字棋游戏
  • Java中的equals()与hashCode()
  • 【绕过open_basedir】
  • 如何用户细分
  • 福彩双色球第2025109期篮球号码分析
  • 思考:客户端负载均衡和服务器负载均衡有什么区别?
  • 网络编程day04/05原始套接字
  • Yarn命令与npm命令的区别与联系(npm:Node.js的官方包管理工具;Yarn:Facebook开发的JavaScript包管理工具)
  • 【大语言模型 67】梯度压缩与稀疏通信
  • LeetCode第365题_水壶问题
  • OpenCV:DNN 模块实现图像风格迁移
  • 锤子助手插件功能六十四:禁用视频前置摄像头镜像
  • OpenHarmony NFC Tag驱动深度剖析:从HDF框架到NDEF读写全流程实战
  • 黑马头条_SpringCloud项目阶段四:多媒体短文章提交功能实现详解
  • TraceID串联数据孤岛:勤源全链路可观测性平台破解微服务“黑箱困境”
  • 随机梯度下降(SGD)算法及其在机器学习中的应用
  • 趣谈bug - the Norway problem