Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am trying to disassemble a compound file that consists of several parts, one of which is an uncompressed kernel sandwiched between several other files. I am trying to find the exact length of the kernel part which is proving difficult.

Is there some indication in the vmlinux header of how much data the bootloader is supposed to read before executing, or is it assumed that all contents of the vmlinux file are to be loaded at handoff from the bootloader?

share|improve this question
    
What format is the file in, perhaps mkimage? What bootloader and on what platform? –  Jonathan Ben-Avraham May 2 '13 at 14:03
add comment

1 Answer

The quick answer is "no", but if this is an ELF image then with some hacking you can probalby find kernel. See the readelf hack below.

The bootloader is responsible to know the format of whatever file in which the kernel and root filesystem reside. This includes knowing the size of the kernel file, in whatever fomat it is. On PowePC and Blackfin, the bootloader is responsible for decompressing the entire kernel if it is compressed, and writing it to it final location in RAM. On ARM, the kernel could be self-decompressing and the bootloader only needs to copy the raw kernel file to a convenient place in RAM and start execution.

If the kernel is self-decompressing, then the symbols that indicate the size of the compressed kernel file might or might not be somewhere in the decompression code at the begining of the file, depending on the decompression algorithm used, but you have no way of knowing where without a linker map for the specific kernel build. Certainly the bootloader has no way of knowing.

The uncompressed kernel code itself is bracketed by two symbols, _stext and _end whose addresses are the start and end of the kernel itself, but do not include the extent of any included initramfs, if an initramfs has been linked into the kernel binary. The extent of the initramfs is set by the linker in two kernel symbols, __initramfs_start and __initramfs_end. Bootloaders generally do not have the capability to read the kernel symbol table (it's in the System.map file), and without this capability they would have no way of knowing where the _end and __initrams_end symbols are in the kernel file. That is, the position of the symbols is not a fixed offset from the start of the binary file. It is determined at link time and can vary depending on the kernel build configuration.

For an uncompressed kernel in ELF format you can probably identify the start of the vmlinux file by looking for the ELF header (177 E L F in the od -c dump of the compound file). You can then do readelf -e or objdump -h on the remainder of the file from this point to find the section with the highest file offset (.shstrtab). Add the section size to this offset and that brings you to the end of vmlinux. I tested this method using an unstripped PPC vmlinux and got size that exactly matched the standalone vnlinux file size. After stripping the kernel this method gave a result that was 1283 bytes short of the stripped image size.

Embedded systems usually use a file fomat such as mkimage to pack the kernel, rootfs, device tree and other components. U-boot for example is mkimage aware, so it knows where the kernel binary begins and ends inside the mkimage file and it knows if the kernel is compressed or not and to what RAM address to write the kernel file.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.