From 92fa6d087f54354e860c9796f260c9e526511252 Mon Sep 17 00:00:00 2001 From: HATAYAMA Daisuke Date: Tue, 13 Mar 2012 19:08:15 +0900 Subject: [PATCH 4/4] Add vmcore snapshot support Currently, snap command uses /proc/iomem as memory map information even if the kernel image it's currently analysing is dumpfile. For dumpfile, I want to use the /proc/iomem information in the dumpfile. This patch makes snap command first check whether the current kernel image is live kernel or dumpfile and then select proper resource for memory mapping information. For an access to resource objects, I used the interface prepared in the previous patch. Signed-off-by: HATAYAMA Daisuke --- extensions/snap.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 51 insertions(+), 3 deletions(-) diff --git a/extensions/snap.c b/extensions/snap.c index dedc286..7f180fc 100644 --- a/extensions/snap.c +++ b/extensions/snap.c @@ -32,7 +32,10 @@ static struct command_table_entry command_table[] = { static char *generate_elf_header(int, int, char *); static int verify_paddr(physaddr_t); -static void init_ram_segments(void); +static void init_ram_segments_live_iomem(void); +static void countup_ram_map(struct resource_data *); +static void get_ram_map(struct resource_data *); +static void init_ram_segments_vmcore_iomem(void); static int print_progress(const char *, ulong); #if defined(X86) || defined(X86_64) || defined(IA64) || defined(PPC64) @@ -114,7 +117,10 @@ cmd_snap(void) if (!filename) cmd_usage(pc->curcmd, SYNOPSIS); - init_ram_segments(); + if (ACTIVE()) + init_ram_segments_live_iomem(); + else + init_ram_segments_vmcore_iomem(); if (!(elf_header = generate_elf_header(type, fd, filename))) error(FATAL, "cannot generate ELF header\n"); @@ -609,7 +615,7 @@ static struct ram_segments *ram_segments = NULL; static int nr_segments = 0; static void -init_ram_segments(void) +init_ram_segments_live_iomem(void) { int i, errflag; FILE *iomem; @@ -676,6 +682,48 @@ fail_iomem: return; } +static void countup_ram_map(struct resource_data *r) +{ + if (STREQ(r->name, "System RAM")) + nr_segments++; +} + +static void get_ram_map(struct resource_data *r) +{ + struct ram_segments *seg; + + if (STREQ(r->name, "System RAM")) { + + seg = &ram_segments[nr_segments]; + + seg->start = PHYSPAGEBASE(r->start); + if (PAGEOFFSET(r->start)) + seg->start += PAGESIZE(); + + seg->end = PHYSPAGEBASE(r->end); + if (PAGEOFFSET(r->end) == (PAGESIZE()-1)) + seg->end += PAGESIZE(); + + nr_segments++; + } +} + +static void init_ram_segments_vmcore_iomem(void) +{ + ulong root = symbol_value("iomem_resource"); + + foreach_resource_tree(root, countup_ram_map); + + if (!nr_segments) + return; + + ram_segments = (struct ram_segments *) + GETBUF(sizeof(struct ram_segments) * nr_segments); + + nr_segments = 0; + foreach_resource_tree(root, get_ram_map); +} + static int verify_paddr(physaddr_t paddr) { -- 1.7.4.4