vmlinux.lds的理解

来源:互联网 发布:黑客编程入门3 pdf 编辑:程序博客网 时间:2024/05/18 12:03

内核源码中使用到的vmlinux.lds总共有两个分别是

1.arch/arm/kernel/vmlinux.lds

2.arch/arm/boot/compressed/vmlinux.lds


其中1用于生成未压缩的内核image

2用于生成经过压缩的内核image


这两个ld 文件中的连接地址有一些区别

/kernel/vmlinux.lds:

421 OUTPUT_ARCH(arm)422 ENTRY(stext)423 jiffies = jiffies_64;424 SECTIONS425 {426  /*427      * XXX: The linker does not define how output sections are428      * assigned to input sections when there are multiple statements429      * matching the same input section name.  There is no documented430      * order of matching.431      *432      * unwind exit sections must be discarded before the rest of the433      * unwind sections get included.434      */435  /DISCARD/ : {436   *(.ARM.exidx.exit.text)437   *(.ARM.extab.exit.text)438 439 440 441 442   *(.exitcall.exit)443   *(.alt.smp.init)444   *(.discard)445   *(.discard.*)446  }447  . = 0xC0000000 + 0x00008000;448  .head.text : {449   _text = .;450   *(.head.text)451  }
compressed/vmlinux.lds

 10 OUTPUT_ARCH(arm) 11 ENTRY(_start) 12 SECTIONS 13 { 14   /DISCARD/ : { 15     *(.ARM.exidx*) 16     *(.ARM.extab*) 17     /* 18      * Discard any r/w data - this produces a link error if we have any, 19      * which is required for PIC decompression.  Local data generates 20      * GOTOFF relocations, which prevents it being relocated independently 21      * of the text/got segments. 22      */ 23     *(.data) 24   } 25  26   . = 0; 27   _text = .;

可以发现压缩内核的连接地址是从0开始的,未压缩的内核连接地址是从0xC0000000+0x00008000开始的。


首先uboot使用到的内核是压缩过的内核也就是uimage,此时内核连接到的是0地址,入口是_start

而vmlinux中有如下定义

  .text : { 30     _start = .; 31     *(.start) 32     *(.text) 33     *(.text.*) 34     *(.fixup) 35     *(.gnu.warning) 36     *(.glue_7t) 37     *(.glue_7) 38   }
所以压缩内核的入口就是连接的0地址开始的。

根据上一篇文章,压缩内核来源于压缩的vmlinux,而压缩的vmlinux是通过head.o, misc.o piggy.o加工而来的。

这个压缩的vmlinux连接顺序可以从arch/arm/boot/compressed/Makefile中得到如下信息

HEAD    = head.oOBJS    += misc.o decompress.ovmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o 

所以其实压缩内核的入口就是arch/arm/boot/compressed/head.s文件,并且这个文件应该也就是uboot跳转到内核之后的总入口,这部分代码是位置无关,所以连接到0地址也没关系。

内核的入口的这段代码应该还包含搬运内核到高地址空间的代码,搬运的目的地址应该就是arch/arm/kernel/vmlinux.lds文件中的连接地址0xC0000000+0x00008000,这也应该改是内核最终的运行地址。








0 0