[Crash-utility] DD image
Dave Anderson
anderson at redhat.com
Tue May 24 13:31:54 UTC 2011
----- Original Message -----
> Hello Dave,
>
> >On the other hand, it would also be fairly easy to create
> >a small utility function that simply pre-pends an ELF header
> >to the dumpfile -- one which has a single PT_LOAD section
> >that describes the physical memory as one large chunk.
> >For this simple format, you could take the snap.c extension
> >module's generate_elf_header() function, have it create a
> >an ELF header with just one PT_LOAD segment, and fold it
> >into a standalone program. It has support for x86, x86_64,
> >ppc64 and ia64.
>
> I have chosen this way for my arm target. Though snap.c told me how to
> create an elf header,
> it is too difficult for me to modify it to support ELF32 of ARM in
> addition to existing ELF64 support. So
> I just prepend a fixed ELF header which generate_elf_header would
> create.
>
> (1) I tried "an ELF header with just one PT_LOAD segment" vmcore file
> as you suggested and got the following,
> ---------------------
> $ ./crash vmlinux vmcore
> crash 5.1.5
> Copyright (C) 2002-2011 Red Hat, Inc.
> ...
> This program has absolutely no warranty. Enter "help warranty" for
> details.
>
> crash: vmcore: not a supported file format
>
> Usage:
>
> crash [OPTION]... NAMELIST MEMORY-IMAGE (dumpfile form)
> crash [OPTION]... [NAMELIST] (live system form)
>
> Enter "crash -h" for details.
> ----------------------
>
> The following is information of the file got by readelf command. Is
> there something wrong?
>
> $ arm-eabi-readelf -a vmcore
> ELF Header:
> Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
> Class: ELF32
> Data: 2's complement, little endian
> Version: 1 (current)
> OS/ABI: UNIX - System V
> ABI Version: 0
> Type: CORE (Core file)
> Machine: ARM
> Version: 0x1
> Entry point address: 0x0
> Start of program headers: 52 (bytes into file)
> Start of section headers: 0 (bytes into file)
> Flags: 0x0
> Size of this header: 52 (bytes)
> Size of program headers: 32 (bytes)
> Number of program headers: 1
> Size of section headers: 0 (bytes)
> Number of section headers: 0
> Section header string table index: 0 <corrupt: out of range>
>
> There are no sections in this file.
>
> There are no sections in this file.
>
> Program Headers:
> Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
> LOAD 0x000054 0xc0000000 0x00000000 0x20000000 0x20000000 RWE 0
>
> There is no dynamic section in this file.
>
> There are no relocations in this file.
>
> There are no unwind sections in this file.
>
> No version information found in this file.
>
> ------------------------------------------------
> (2) Next I tried "an ELF header with an empty PT_NOTE segment and just
> one PT_LOAD segment"
> This time readelf command shows
> Program Headers:
> Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
> NOTE 0x000074 0x00000000 0x00000000 0x00000 0x00000 0
> LOAD 0x000074 0xc0000000 0x00000000 0x20000000 0x20000000 RWE 0
That's what you need -- it is presumed that there will be a minimum
of two program header sections:
(1) at least one PT_NOTE section (typically an NT_PRSTATUS note w/registers)
(2) at least one PT_LOAD section (which you have)
so without the empty PT_NOTE, it was failing here in is_netdump():
if ((elf32->e_ident[EI_CLASS] == ELFCLASS32) &&
(swap16(elf32->e_type, swap) == ET_CORE) &&
(swap32(elf32->e_version, swap) == EV_CURRENT) &&
(swap16(elf32->e_phnum, swap) >= 2)) {
because your elf32->e_phnum was 1:
> Number of program headers: 1
So, yes, adding an empty PT_NOTE should be OK to get by that error.
> And I could use this file as a core file for "arm-eabi-gdb vmlinux > vmcore"
> For example "show init_task" works normally.
>
> Is this an expected behavior?
>
> (3) Above vmcore file works for gdb, but it does not work for crash(5.1.5).
> I got the following message and the crash command just exited.
> crash: CONFIG_SPARSEMEM kernels not supported for this architecture
>
> Would you please tell me how to support CONFIG_SPARSEMEM?
>
> I tried to add "machdep->max_physmem_bits = _MAX_PHYSMEM_BITS;" in
> arm.c and made some progress. But still I cannot reach the crash prompt.
>
> I will appreciate any suggestion.
As far as the CONFIG_SPARSEMEM failure, I'm not exactly sure why that's
happening.
Looking at the latest upstream kernel, CONFIG_SPARSEMEM is not supported
by the ARM architecture. This is "arch/arm/include/asm/sparsemem.h":
#ifndef ASMARM_SPARSEMEM_H
#define ASMARM_SPARSEMEM_H
#include <asm/memory.h>
/*
* Two definitions are required for sparsemem:
*
* MAX_PHYSMEM_BITS: The number of physical address bits required
* to address the last byte of memory.
*
* SECTION_SIZE_BITS: The number of physical address bits to cover
* the maximum amount of memory in a section.
*
* Eg, if you have 2 banks of up to 64MB at 0x80000000, 0x84000000,
* then MAX_PHYSMEM_BITS is 32, SECTION_SIZE_BITS is 26.
*
* Define these in your mach/memory.h.
*/
#if !defined(SECTION_SIZE_BITS) || !defined(MAX_PHYSMEM_BITS)
#error Sparsemem is not supported on this platform
#endif
#endif
And "arch/arm/include/asm/memory.h" does not define either
SECTION_SIZE_BITS or MAX_PHYSMEM_BITS.
In any case, the "CONFIG_SPARSEMEM kernels not supported..."
error message is printed in sparse_mem_init(). But that function
should return immediately because IS_SPARSEMEM() should be FALSE
because the SPARSEMEM bit should not be set:
#define IS_SPARSEMEM() (vt->flags & SPARSEMEM)
void
sparse_mem_init(void)
{
ulong addr;
ulong mem_section_size;
int dimension;
if (!IS_SPARSEMEM())
return;
... [ cut ] ...
if (!MAX_PHYSMEM_BITS())
error(FATAL,
"CONFIG_SPARSEMEM kernels not supported for this architecture\n");
In your case, IS_SPARSEMEM() is returning TRUE because
the SPARSEMEM bit in vt->flags is getting set here:
if (kernel_symbol_exists("mem_section"))
vt->flags |= SPARSEMEM;
... [ cut ] ...
sparse_mem_init();
I have 3 sample ARM dumpfiles, versions 2.6.35-rc3, 2.6.36-rc6, and
2.6.38-rc2, and none of them have a "mem_section" variable, so it
does not make it to the "if (!MAX_PHYSMEM_BITS())" check above.
The kernel's "mem_section" variable is declared in mm/sparse.c:
#ifdef CONFIG_SPARSEMEM_EXTREME
struct mem_section *mem_section[NR_SECTION_ROOTS]
____cacheline_internodealigned_in_smp;
#else
struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT]
____cacheline_internodealigned_in_smp;
#endif
EXPORT_SYMBOL(mem_section);
But the mm/Makefile only builds sparse.c into the kernel if
CONFIG_SPARSEMEM is turned on:
obj-$(CONFIG_SPARSEMEM) += sparse.o
So I don't understand how your kernel could have (and compile with)
a "mem_section" variable, since it needs MAX_PHYSMEM_BITS?
Dave
More information about the Crash-utility
mailing list