Re: How vmlinux is recognized?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I loved this reply.......can I annotate it with references to the linux kernel sources?

On Fri, May 13, 2011 at 9:42 AM, Dave Hylands <dhylands@xxxxxxxxx> wrote:
Hi Vikram,

...snip...
> So when compiling the kernel, what is the purpose of the other
> files(mentioned below)
> linux-2.6/vmlinux - ELF executable, not stripped
> linux-2.6/arch/x86/boot/vmlinux.bin - Raw binary (Guess this is the
> one which is inside the bzImage)
> linux-2.6/arch/x86/boot/compressed/vmlinux.bin - ELF executable, stripped
> linux-2.6/arch/x86/boot/compressed/vmlinux - ELF executable, not stripped

Take luca's email and start at the bottom working towards the top.

linux-2.6/vmlinux is the output of the linker. As such, it is an ELF file.
A binary is then extracted from this to create
arch/x86/boot/compressed/vmlinux.bin

yes:

See ./arch/x86/boot/Makefile
 
This binary is then compressed to produce
arch/x86/boot/compressed/vmlinux.bin.gz

See ./arch/x86/boot/compressed/Makefile
 
This gzipped binary is then converted into an object file (which just
contains the gzipped data) but now we're back to having an ELF file

./arch/x86/boot/compressed/mkpiggy.c is compiled into a commandline binary - mkpiggy which will generate the piggy.o.
 
called arch/x86/boot/compressed/piggy.o
The linker then compiles a decompressor (misc.o) and piggy.o together

Yes, the routine is called "decompress_kernel", residing inside ./arch/x86/boot/compressed/misc.c.   And this routine is called from ./arch/x86/boot/compressed/head_32.S (or head_64.S) and at runtime, the gzipped data is decompressed and immediately jumped into (perhaps after some relocation if needed):

/*
 * Do the decompression, and jump to the new kernel..
 */
        leal    z_extract_offset_negative(%ebx), %ebp
                                /* push arguments for decompress_kernel: */
        pushl   %ebp            /* output address */
        pushl   $z_input_len    /* input_len */
        leal    input_data(%ebx), %eax
        pushl   %eax            /* input_data */
        leal    boot_heap(%ebx), %eax
        pushl   %eax            /* heap area */
        pushl   %esi            /* real mode pointer */
        call    decompress_kernel
        addl    $20, %esp


to produce arch/x86/boot/compressed/vmlinux (an ELF file).
objcopy is used again to convert this ELF into a binary:
arch/x86/boot/compressed/vmlinux arch/x86/boot/vmlinux.bin
Finally, the binary is compressed to produce bzImage.

Inside arch/x86/boot/Makefile:

Creating the vmlinux.bin from vmlinux via objcopy (note that this operation will throw all relocation information):

$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
        $(call if_changed,objcopy)

And then packing together linearly to form the "bzImage" (output from make):

make -f scripts/Makefile.build obj=arch/x86/boot arch/x86/boot/bzImage

make -f scripts/Makefile.build obj=arch/x86/boot/compressed arch/x86/boot/compressed/vmlinux

arch/x86/boot/tools/build arch/x86/boot/setup.bin arch/x86/boot/vmlinux.bin CURRENT > arch/x86/boot/bzImage


So what you get is a compressed binary which contains a decompressor
and another compressed binary, this inner compressed binary being the
kernel.

GRUB loads bzImage into memory and decompresses it and then executes
the resulting binary.

To be more precise, grub will load bzImage and jump into the startup_32 function located in arch/x86/boot/compressed/head_32.S at the following fixed address (from source code):

/*
 *  head.S contains the 32-bit startup code.
 *
 * NOTE!!! Startup happens at absolute address 0x00001000, which is also where
 * the page directory will exist. The startup code will be overwritten by
 * the page directory. [According to comments etc elsewhere on a compressed
 * kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC]
 *
 * Page 0 is deliberately kept safe, since System Management Mode code in
 * laptops may need to access the BIOS data stored there.  This is also
 * useful for future device drivers that either access the BIOS via VM86
 * mode.
 */

More info:

http://books.google.com/books?id=e8BbHxVhzFAC&pg=PA1224&lpg=PA1224&dq=grub+head_32.S&source=bl&ots=0MSdKwBoM6&sig=2RyEpprl25zueiqi332TQHLIj0E&hl=en&ei=y5vQTY7eBNDNrQeI3bTCCg&sa=X&oi=book_result&ct=result&resnum=3&ved=0CCkQ6AEwAg#v=onepage&q=grub%20head_32.S&f=false
 
This binary starts with a decompressor which then decompresses the
kernel, and executes the resulting binary.
This binary may relocate itself (probably depends on the architecture)
to a different spot in memory, and then runs.
The kernel is now running.

--
Dave Hylands
Shuswap, BC, Canada
http://www.davehylands.com

_______________________________________________
K

--
Regards,
Peter Teoh
_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux