mkimge的參數”-e”決定kernel entry point address, 由於zImage是一個 raw binary file, 所以zImage dump在memory時起始位置所擺內容即是the lowest ELF section of vmlinux (arch/arm/boot/compressed/vmliux) , .text 為該section, link script  "arch/arm/boot/compressed/vmlinux.lds"決定vmlinux內的sections排列順序: (1)vmlinux的起始位置是0,  (2).text起始位置是0, (3)the first byte of .text 所放的指令.start 即是vmlinux的entry point (_start), 該link script (有關.text部份) 如下所示:
OUTPUT_ARCH(arm)
ENTRY(_start)          //the entry point
SECTIONS
{
  . = 0;                //The  current ouput location counter is moved to "0".
  _text = .;            //The  current ouput location counter  is assigned to _text (the starting address of .text)
  .text : {
    _start = .;            // The  current ouput location counter  is assigned to _start
    *(.start)            // Include all input .start  sections
    *(.text)
    *(.text.*)
    *(.fixup)
    *(.gnu.warning)
    *(.rodata)
    *(.rodata.*)
    *(.glue_7)
    *(.glue_7t)
    *(.piggydata)
    . = ALIGN(4);
  }
  _etext = .;                 // "_text + SIZEOF(.text)" is assigned to _etext
....   
} 
所以vmlinux(zImage)的 entry point 為.start (arch/arm/boot/compressed/head.S定義該section), 因為vmlinux(zImage)的 entry point在 address 0,  head.S 需要做relocation 動作讓vmlinux(zImage)可以被載入到任意的physical memory address執行。需不需要做relocate由以下動作做判斷:
        adr    r0, LC0        @r0=offset between LC0 and  _start (program entry pointer), 若zImage載入到physical memory address 0x20008040執行那_start address就是0x20008040。
        ldmia    r0, {r1, r2, r3, r4, r5, r6, ip, sp}
        subs    r0, r0, r1        @ calculate the delta offset. 所以目前r0=_start (program entry pointer) address
                        @ if delta is zero, we are
        beq    not_relocated        @ running at the address we
                        @ were linked at.
        /*
         * We're running at a different address.  We need to fix
         * up various pointers:
         *   r5 - zImage base address
         *   r6 - GOT start
         *   ip - GOT end
         */
        add    r5, r5, r0
        add    r6, r6, r0
        add    ip, ip, r0
        ....
        LC0:        .word    LC0            @ r1
        .word    __bss_start        @ r2
        .word    _end            @ r3
        .word    zreladdr        @ r4
        .word    _start            @ r5
        .word    _got_start        @ r6
        .word    _got_end        @ ip
        .word    user_stack+4096        @ sp
在arch/arm/mach-xxx/Makefile.boot 定義”zreladdr-y”值, 該值是piggy.gz decompress 後的Image (kernel proper without debug symbols)的entry point address ,該entry point address與zImage的 entry point address無關。
arch/arm/boot/compressed/head.S的工作是(1) relocate zImage base address  ,GOT table address and GOT table entries,  (2)enable MMU for using I/D cache for quickly  decompressing  piggy.gz (kernel proper ) , (3)copy the decomprssed codes to the memory space of address ”zreladdr-y”(in r4)(4) flush I/D cache and  disable MMU, (5)restore r0=0, r1=machine id, and r3=ATAG pointer , (6) mov    pc, r4  。
 
沒有留言:
張貼留言