Understanding Kdump (How to make vmcoreinfo_note)


vmcoreinfo_note contains crash kernel general information, include os version, page size etc.. In kernel, vmcoreinfo_note is stored on vmcoreinfo_note[]. And, vmcoreinfo_note is one part of /proc/vmcore, which is used for debugging with capture kernel brings up. In blog "Understanding Kdump (Loading Part)", one program header including vmcoreinfo_note's address and length was referenced, and this program header could be got from "elfcorehdr". vmcoreinfo_note[]'s address and length could be got by reading /sys/kernel/vmcoreinfo.

When kexec is configured, this function will be triggered with kernel brings up.

1458 static int __init crash_save_vmcoreinfo_init(void)
1459 {
1460         VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
1461         VMCOREINFO_PAGESIZE(PAGE_SIZE);
1462
1463         VMCOREINFO_SYMBOL(init_uts_ns);
1464         VMCOREINFO_SYMBOL(node_online_map);
1465         VMCOREINFO_SYMBOL(swapper_pg_dir);
1466         VMCOREINFO_SYMBOL(_stext);
1467         VMCOREINFO_SYMBOL(vmlist);
1468
1469 #ifndef CONFIG_NEED_MULTIPLE_NODES
1470         VMCOREINFO_SYMBOL(mem_map);
1471         VMCOREINFO_SYMBOL(contig_page_data);
1472 #endif
1473 #ifdef CONFIG_SPARSEMEM
1474         VMCOREINFO_SYMBOL(mem_section);
1475         VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
1476         VMCOREINFO_STRUCT_SIZE(mem_section);
1477         VMCOREINFO_OFFSET(mem_section, section_mem_map);
1478 #endif
1479         VMCOREINFO_STRUCT_SIZE(page);
1480         VMCOREINFO_STRUCT_SIZE(pglist_data);
1481         VMCOREINFO_STRUCT_SIZE(zone);
1482         VMCOREINFO_STRUCT_SIZE(free_area);
1483         VMCOREINFO_STRUCT_SIZE(list_head);
1484         VMCOREINFO_SIZE(nodemask_t);
1485         VMCOREINFO_OFFSET(page, flags);
1486         VMCOREINFO_OFFSET(page, _count);
1487         VMCOREINFO_OFFSET(page, mapping);
1488         VMCOREINFO_OFFSET(page, lru);
1489         VMCOREINFO_OFFSET(pglist_data, node_zones);
1490         VMCOREINFO_OFFSET(pglist_data, nr_zones);
1491 #ifdef CONFIG_FLAT_NODE_MEM_MAP
1492         VMCOREINFO_OFFSET(pglist_data, node_mem_map);
1493 #endif
1494         VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
1495         VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
1496         VMCOREINFO_OFFSET(pglist_data, node_id);
1497         VMCOREINFO_OFFSET(zone, free_area);
1498         VMCOREINFO_OFFSET(zone, vm_stat);
1499         VMCOREINFO_OFFSET(zone, spanned_pages);
1500         VMCOREINFO_OFFSET(free_area, free_list);
1501         VMCOREINFO_OFFSET(list_head, next);
1502         VMCOREINFO_OFFSET(list_head, prev);
1503         VMCOREINFO_OFFSET(vm_struct, addr);
1504         VMCOREINFO_LENGTH(zone.free_area, MAX_ORDER);
1505         log_buf_kexec_setup();
1506         VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
1507         VMCOREINFO_NUMBER(NR_FREE_PAGES);
1508         VMCOREINFO_NUMBER(PG_lru);
1509         VMCOREINFO_NUMBER(PG_private);
1510         VMCOREINFO_NUMBER(PG_swapcache);
1511
1512         arch_crash_save_vmcoreinfo();
1513         update_vmcoreinfo_note();
1514
1515         return 0;
1516 }

149 #define VMCOREINFO_OSRELEASE(value) \
150         vmcoreinfo_append_str("OSRELEASE=%s\n", value)
151 #define VMCOREINFO_PAGESIZE(value) \
152         vmcoreinfo_append_str("PAGESIZE=%ld\n", value)
153 #define VMCOREINFO_SYMBOL(name) \
154         vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name)
155 #define VMCOREINFO_SIZE(name) \
156         vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
157                               (unsigned long)sizeof(name))
158 #define VMCOREINFO_STRUCT_SIZE(name) \
159         vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \
160                               (unsigned long)sizeof(struct name))
161 #define VMCOREINFO_OFFSET(name, field) \
162         vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \
163                               (unsigned long)offsetof(struct name, field))
164 #define VMCOREINFO_LENGTH(name, value) \
165         vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value)
166 #define VMCOREINFO_NUMBER(name) \
167         vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name)
168 #define VMCOREINFO_CONFIG(name) \
169         vmcoreinfo_append_str("CONFIG_%s=y\n", #name)

1428 void vmcoreinfo_append_str(const char *fmt, ...)
1429 {
1430         va_list args;
1431         char buf[0x50];
1432         int r;
1433
1434         va_start(args, fmt);
1435         r = vsnprintf(buf, sizeof(buf), fmt, args);
1436         va_end(args);
1437
1438         if (r + vmcoreinfo_size > vmcoreinfo_max_size)
1439                 r = vmcoreinfo_max_size - vmcoreinfo_size;
1440
1441         memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
1442
1443         vmcoreinfo_size += r;
1444 }
vmcoreinfo_append_str() store necemmory vmcore information to vmcoreinfo_data[]. The address&length will be got by reading /proc/kernel/vminfo.
1411 static void update_vmcoreinfo_note(void)
1412 {
1413         u32 *buf = vmcoreinfo_note;
1414
1415         if (!vmcoreinfo_size)
1416                 return;
1417         buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
1418                               vmcoreinfo_size);
1419         final_note(buf);
1420 }
update_vmcoreinfo_note-> update_vmcoreinfo_note
1179 static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
1180                             size_t data_len)
1181 {
1182         struct elf_note note;
1183
1184         note.n_namesz = strlen(name) + 1;
1185         note.n_descsz = data_len;
1186         note.n_type   = type;
1187         memcpy(buf, &note, sizeof(note));
1188         buf += (sizeof(note) + 3)/4;
1189         memcpy(buf, name, note.n_namesz);
1190         buf += (note.n_namesz + 3)/4;
1191         memcpy(buf, data, note.n_descsz);
1192         buf += (note.n_descsz + 3)/4;
1193
1194         return buf;
1195 }
update_vmcore_info will transfer vmcoreinfo_data to vmcoreinfo_note. When crash happens, another string “CRASHTIME=xxx” will append vmcoreinfo_data, which also will overwrite vmcoreinfo_note. The final layout of the vmcoreinfo_note illustrate below.

评论

此博客中的热门博文

Linux/ARM Page Table Entry 属性设置分析

提交了30次才AC ---【附】POJ 2488解题报告

笔记