内核源码中使用到的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 SECTIONS 425 { 426 /* 427 * XXX: The linker does not define how output sections are 428 * assigned to input sections when there are multiple statements 429 * matching the same input section name. There is no documented 430 * order of matching. 431 * 432 * unwind exit sections must be discarded before the rest of the 433 * 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 = .;
首先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.o OBJS += misc.o decompress.o vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o
内核的入口的这段代码应该还包含搬运内核到高地址空间的代码,搬运的目的地址应该就是arch/arm/kernel/vmlinux.lds文件中的连接地址0xC0000000+0x00008000,这也应该改是内核最终的运行地址。