----- 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 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility