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, ¬e, 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.
评论
发表评论