The overall format of an AArch64 Linux kernel can be found in https://www.kernel.org/doc/Documentation/arm64/booting.txt
Of particular note (emphasis mine):
The AArch64 kernel does not currently provide a decompressor and
therefore requires decompression (gzip etc.) to be performed by the
boot loader if a compressed Image target (e.g. Image.gz) is used. For
bootloaders that do not implement this requirement, the uncompressed
Image target is available instead.
and indeed, I downloaded a sample image from Linaro and its header matches the structure in section 4, i.e. the image is uncompressed.
hex dump of the header:
0000000000: 4D 5A 00 91 57 00 00 14 │ 00 00 08 00 00 00 00 00 MZ.............
0000000010: 00 70 A8 00 00 00 00 00 │ 00 00 00 00 00 00 00 00 ...............
0000000020: 00 00 00 00 00 00 00 00 │ 00 00 00 00 00 00 00 00 ...............
0000000030: 00 00 00 00 00 00 00 00 │ 41 52 4D 64 40 00 00 00 ........ARMd@...
You can see the magic
field at offset 0x38 (0x644d5241
or "ARM\x64" as text).
The "MS-DOS executable" text shown by file
is a red herring: the overall image format is actually Portable Executable (PE), which has to start with the MZ
signature. Linux kernel employs a few tricks to appear like a valid PE file so that it can be booted by a UEFI-compliant firmware.
There is no "elf bibnary" to extract because the kernel has been linked into the PE file format and does not contain any ELF headers anymore. IF you want to disassemble it, just disassemble it as raw AArch64 binary (e.g. pass -bbinary -maarch64
flags to an ARM objdump
) - the second instruction will jump to the real entrypoint:
0000 4D 5A 00 91 ADD X13, X18, #0x16
0004 57 00 00 14 B stext
(see arch/arm64/kernel/head.S
in kernel sources for more details).