Linux系统移植:U-Boot 链接脚本
Linux系统移植:U-Boot 链接脚本
一、u-boot.lds 介绍
前面提到的 U-Boot 的本质就是一个大的裸机程序,执行的时候需要先找到程序入口,而程序的链接是由链接脚本来决定的,所以 通过链接脚本可以找到程序的入口,编译一下 uboot,编译完成以后就会在 uboot 根目录下生成 u-boot.lds 文件,如下
只有编译 u-boot 以后才会在根目录下出现 u-boot.lds 文件
二、u-boot.lds 分析
打开 u-boot.lds 文件,分析其代码:
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
*(.__image_copy_start)
*(.vectors)
arch/arm/cpu/armv7/start.o (.text*)
*(.text*)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : {
*(.data*)
}
. = ALIGN(4);
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN(4);
.image_copy_end :
{
*(.__image_copy_end)
}
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rel.dyn : {
*(.rel*)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
.end :
{
*(.__end)
}
_image_binary_end = .;
. = ALIGN(4096);
.mmutable : {
*(.mmutable)
}
.bss_start __rel_dyn_start (OVERLAY) : {
KEEP(*(.__bss_start));
__bss_base = .;
}
.bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN(4);
__bss_limit = .;
}
.bss_end __bss_limit (OVERLAY) : {
KEEP(*(.__bss_end));
}
.dynsym _image_binary_end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
.plt : { *(.plt*) }
.interp : { *(.interp*) }
.gnu.hash : { *(.gnu.hash) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
.gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
这里我们主要注意链接脚本中的 .text 段
其中 ENTRY(_start) 是整个函数的入口,_start 在 arch/arm/lib/vectors.S 中有定义,代码如下:
*(.__image_copy_start) 链接镜像启动地址,对于 .text 来说他的起始地址是 0X87800000,这里直接链接了该文件,我们在 map 文件中看一下 __image_copy_start 中的链接地址能不能对应上,这里在 uboot.map 中可以看到链接地址对上了:
*(.vectors) 用于链接 vectors 段中保存的中断向量表地址,在 map 中我们可以看到:
arch/arm/cpu/armv7/start.o (.text*) 代码将编译出来的代码放到中断向量表后面
*(.text*) 用于放其他的代码段
后面的一些特殊变量对应着一些地址:
变量 | 数值 | 描述 |
---|---|---|
__image_copy_start | 0x87800000 | uboot 拷贝的首地址 |
__image_copy_end | 0x8785dd54 | uboot 拷贝的结束地址 |
__rel_dyn_start | 0x8785dd54 | .rel.dyn 段起始地址 |
__rel_dyn_end | 0x878668f4 | .rel.dyn 段结束地址 |
_image_binary_end | 0x878668f4 | 镜像结束地址 |
__bss_start | 0x8785dd54 | .bss 段起始地址 |
__bss_end | 0x878a8e74 | .bss 段结束地址 |
这些地址对应的值可以通过 grep 查找,如下查找 __image_copy_start
grep -nR "__image_copy_start"
- 1
查找如下:
文章来源: blog.csdn.net,作者:JeckXu666,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_45396672/article/details/121977581
- 点赞
- 收藏
- 关注作者
评论(0)