unknown arm linux kernel image format

2

I have a ARM linux kernel image file. but I am not sure exactly what kind of format it is...

the 'file' command tells me that it is pure data.

first, I thought it is vmlinuz and tried to decompress it.

I searched 'gzip' header signature and uncompressed from there.

but all I got is following makefile script.

#
# Automatically generated make config: don't edit
# Linux/arm 2.6.38.7 Kernel Configuration
# Sat Apr 28 17:29:46 2012
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_HAVE_SCHED_CLOCK=y
CONFIG_ARCH_SCHED_CLOCK=y
# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_KTIME_SCALAR=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_VECTORS_BASE=0xffff0000
# CONFIG_ARM_PATCH_PHYS_VIRT is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
CONFIG_HAVE_IRQ_WORK=y
CONFIG_IRQ_WORK=y

#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_LZO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_HAVE_GENERIC_HARDIRQS=y

#
# IRQ subsystem
#
CONFIG_GENERIC_HARDIRQS=y
# CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED is not set
CONFIG_HAVE_SPARSE_IRQ=y
CONFIG_GENERIC_IRQ_SHOW=y
# CONFIG_GENERIC_PENDING_IRQ is not set
# CONFIG_AUTO_IRQ_AFFINITY is not set
# CONFIG_IRQ_PER_CPU is not set
CONFIG_SPARSE_IRQ=y

#
# RCU Subsystem
#
CONFIG_TREE_RCU=y
# CONFIG_PREEMPT_RCU is not set
# CONFIG_RCU_TRACE is not set
CONFIG_RCU_FANOUT=32
# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
# CONFIG_CGROUP_NS is not set
# CONFIG_CGROUP_FREEZER is not set
# CONFIG_CGROUP_DEVICE is not set
CONFIG_CPUSETS=y
CONFIG_PROC_PID_CPUSET=y
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_RESOURCE_COUNTERS is not set
# CONFIG_CGROUP_SCHED is not set
# CONFIG_BLK_CGROUP is not set
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
# CONFIG_HAVE_GET_CYCLES is not set
# CONFIG_HAVE_TRACE_CLOCK is not set
CONFIG_HAVE_TRACE_CLOCK_GENERIC=y
CONFIG_HAVE_TRACE_CLOCK_32_TO_64=y
# CONFIG_HAVE_UNSYNCHRONIZED_TSC is not set
# CONFIG_SCHED_AUTOGROUP is not set
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
# CONFIG_EXPERT is not set
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y

#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
# CONFIG_PERF_COUNTERS is not set
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
CONFIG_PROFILING=y
# CONFIG_MARKERS is not set
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set

I thoroughly looked at the binary with hexdump. I think this is a pure ARM binary file.

first few bytes were disassembled as follows

 msr    CPSR_c, #211    ; 0xd3
 mrc    15, 0, r9, cr0, cr0, {0}
 bl 0x000148e0
 movs   sl, r5
 beq    0x00014924
 add    r3, pc, #44 ; 0x2c
 ldm    r3, {r4, r8}
 sub    r4, r3, r4
 add    r8, r8, r4
 bl 0x00000154
 bl 0x0000018c
 bl 0x00000050
 ldr    sp, [pc, #12]   ; 0x00000044
 add    lr, pc, #4
 mov    r8, r4
 add    pc, sl, #16
 b  0x00014894
 andhi  r8, r0, r8, ror #3
 andhi  r8, r0, r8, asr #32
 andhi  r0, r0, r0
 add    r4, r8, #16384  ; 0x4000
 mov    r0, r4
 mov    r3, #0
 add    r6, r0, #16384  ; 0x4000
 str    r3, [r0], #4
 str    r3, [r0], #4
 str    r3, [r0], #4
 str    r3, [r0], #4
 teq    r0, r6
 bne    0x00000060
 ldr    r7, [sl, #8]
 add    r0, pc, #196    ; 0xc4
 ldm    r0, {r3, r5, r6}
 sub    r0, r0, r3
 add    r5, r5, r0
 add    r6, r6, r0
 lsr    r5, r5, #20
 lsr    r6, r6, #20
 orr    r3, r7, r5, lsl #20
 str    r3, [r4, r5, lsl #2]
 cmp    r5, r6
 addcc  r5, r5, #0
 bcc    0x00000098
 mov    r3, pc
 lsr    r3, r3, #20
 orr    r3, r7, r3, lsl #20
 add    r0, r4, #8192   ; 0x2000
 str    r3, [r0, #0]!
 ldr    r6, [pc, #124]  ; 0x00000144
 add    r0, r0, #4
 add    r6, r4, r6, lsr #18
 cmp    r0, r6
 add    r3, r3, #1048576    ; 0x100000
 strls  r3, [r0], #4
 bls    0x000000cc
 lsr    r0, r2, #20
 lsls   r0, r0, #20
 moveq  r0, r8
 sub    r3, r0, r8
 add    r3, r3, #-2147483648    ; 0x80000000
 add    r3, r4, r3, lsr #18
 orr    r6, r7, r0
 str    r6, [r3]
 mov    r7, #36864  ; 0x9000
 orr    r3, r7, #-134217728 ; 0xf8000000
 orr    r7, r7, #268435456  ; 0x10000000
 lsr    r3, r3, #20
 lsl    r3, r3, #2

....

this is the kernel image file used for booting process for ARM simulator(SoC designer). and it works fine.

what I want is the ELF file of this kernel which I can open with disassembler like IDA.

but I cant retrieve original ELF formatted file from this kernel image...

some help would be appreciated.

thank you in advance.

linux
kernel
arm
asked on Stack Overflow Feb 10, 2013 by daehee

1 Answer

6

ARM Linux kernels are usually self-loading plain binaries, generated from the original ELF by extracting the code+rdata sections from it and appending the "piggy" loader. They're loaded by the bootloader at some place in the memory and just run from there. The piggy loader unpacks/copies the main payload to the final address and jumps to it.

Restoring ELF from the binary might be possible (the final runtime address is usually fixed to 0xC0008000, and you can find out .data/.bss ranges by analyzing boot code), but the symbol table is trickier. Recent kernels don't use ELF symbol table as-is but employ compression to save space. If you can boot the kernel, the easiest way is to read /proc/ksyms or /proc/kallsyms as it will have the symbols in uncompressed format. Otherwise you'd have to find the compressed table in the binary and decompress it manually.

answered on Stack Overflow Feb 11, 2013 by Igor Skochinsky • edited Nov 15, 2018 by Igor Skochinsky

User contributions licensed under CC BY-SA 3.0