驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址

最近重新看了乾龙_Heron的《ARM 上电启动及 Uboot 代码分析》(下简称《代码分析》)

文档里写道:

Uboot.lds文件中起始地址是0x00,但是config.mk中的TEXT_BASE是0x57e00000,但是生成的uboot反汇编文件中,为什
么start.s的第一条指令地址也是0x57e00000?不应该是0x00么?因为start.s的加载地址和运行地址都是0x00啊!? 答:Uboot.lds的0x00: 跟在SECTION后面的第一条 location counter,总是默认初始化为0。config.mk中的TEXT_BASE就是ROM在CPU上的地址,也就是说,
不同的CPU已经规定了不同的ROM地址

 

先来看看笔者这篇文章标题的关键字:链接地址 加载地址

《代码分析》中也给了答案

 连接地址<==>运行地址

 存储地址<==>加载地址

(1)对于有操作系统时,运行地址与加载地址不同,在加载过程中装载器就把段加载到它应该去的连接地址处(也就是生成该段时的运行地址)

(2)对于uboot,运行地址与加载地址不同时,需要它自己(例如前4k代码)将自己加载到运行地址处执行。

  

那么什么是链接脚本地址,来看一段链接脚本的内容:

SECTIONS

{

       . = 0x08048000;

       tinytext : { *(.test) *(.rodata)}

       . = 0x08088000;

       tinydata : {*(.data)}

}

用过脚本代码的人知道,.test段和.rodata将紧跟在0x08048000地址后面,这种在链接脚本上假定的地址,称为链接脚本地址(未知是否有更专业的名称,暂用此名)。为什么我要说是假定呢?因为在ld命令中可以覆盖lds脚本设定段的地址,就是《代码分析》中出现的.lds的地址被.mk文件(.mk文件,其实就是makefile文件)中的TEXT_BASE修改了。

上面已经提到,链接地址就是代码运行地址,运行地址我们可以通过对执行文件的反汇编得到;那我们来做一个实验,看lds文件中的地址是不是代码链接地址,

下面用gcc -c 和 ld 来编译链接代码(参考程序员的自我修养 p125)

c代码

int aa=8;

void main(void)

{

       int i=0;

       aa = i;

}

.lds 代码

ENTRY(main)
SECTIONS {
. = 0x08048000; tinytext : { *(.test) *(.rodata)} . = 0x08088000; tinydata : {*(.data)}
} 然后 $ gcc -c -fno-builtin ttext.c
$ ld -static -T test_Ttext.lds -o ttext ttext.o
$ objdump -S ttext ttext: file format elf64-x86-64
Disassembly of section .text:
0000000008048000 <main>:
8048000: 55 push %rbp
8048001: 48 89 e5 mov %rsp,%rbp
8048004: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
804800b: 8b 45 fc mov -0x4(%rbp),%eax
804800e: 89 05 ec ff 03 00 mov %eax,0x3ffec(%rip) # 8088000 <aa>
8048014: 5d pop %rbp
8048015: c3 retq 我们看看符号表:
$ objdump -t ttext
ttext: file format elf64-x86-64
SYMBOL TABLE:
0000000008048000 l d .text 0000000000000000 .text
0000000008048018 l d .eh_frame 0000000000000000 .eh_frame
0000000008088000 l d tinydata 0000000000000000 tinydata
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 l df *ABS* 0000000000000000 ttext.c
0000000000000000 l df *ABS* 0000000000000000
0000000008088000 g O tinydata 0000000000000004 aa
0000000008048000 g F .text 0000000000000016 main

  

从上面这个实验,我们可以看出来,链接脚本地址和链接地址居然是一样的!

那么,到底.mk文件里面做了什么,使TEXT_BASE成为了代码的地址?关键一点就是.mk在ld 中加了一个选项 -Ttext,这个选项使得.text地址的链接地址为此选项的参数TEXT_BASE。

我们来看一下是不是:

之前我们的ld没有加选项-Ttext,现在加上试试

$ ld -static -T test_Ttext.lds -o ttext ttext.o -Ttext 0xff

$ objdump -S ttext
ttext: file format elf64-x86-64
Disassembly of section .text:
00000000000000ff <main>:
ff: 55 push %rbp
100: 48 89 e5 mov %rsp,%rbp
103: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
10a: 8b 45 fc mov -0x4(%rbp),%eax
10d: 89 05 ed 7e 08 08 mov %eax,0x8087eed(%rip) # 8088000 <aa>
113: 5d pop %rbp
114: c3 retq 我们可以发现,.text的地址变成了0xff 跟我们输入的参数一样
再看看符号表 $ objdump -t ttext ttext: file format elf64-x86-64 SYMBOL TABLE: 0000000008088000 l d tinydata 0000000000000000 tinydata 00000000000000ff l d .text 0000000000000000 .text 0000000008088008 l d .eh_frame 0000000000000000 .eh_frame 0000000000000000 l d .comment 0000000000000000 .comment 0000000000000000 l df *ABS* 0000000000000000 ttext.c 0000000000000000 l df *ABS* 0000000000000000 0000000008088000 g O tinydata 0000000000000004 aa 00000000000000ff g F .text 0000000000000016 main

  

.text 段地址的确是变了,但是没有影响 data段

在这样的试验结果下,可以确定的说,-Ttext选项会改变.text段的地址,这就是TEXT_BASE成为Uboot的代码段链接地址的原因


文章讨论Uboot代码段链接地址的问题到这里就结束了,下面将测试-Ttext 选项对.data是否会产生影响;

上面的实验将.data放在另一段,如果将.data放在tinytext中,是否会随着-Ttext改变.text的时候同时被改变呢?

$ cat test_Ttext.lds

ENTRY(main)

SECTIONS
{ . = 0x08048000; tinytext : { *(.test)*(.data) *(.rodata)}
} $ ld -static -T test_Ttext.lds -o ttext ttext.o -Ttext 0xff
$ objdump -S ttext
ttext: file format elf64-x86-64
Disassembly of section .text:
00000000000000ff <main>:
ff: 55 push %rbp
100: 48 89 e5 mov %rsp,%rbp
103: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
10a: 8b 45 fc mov -0x4(%rbp),%eax
10d: 89 05 ed 7e 04 08 mov %eax,0x8047eed(%rip) # 8048000 <aa>
113: 5d pop %rbp
114: c3 retq 咦,怎么aa变成了tinytext的地址呢?
我们看看符号表
$ objdump -t ttext
ttext: file format elf64-x86-64
SYMBOL TABLE:
0000000008048000 l d tinytext 0000000000000000 tinytext
00000000000000ff l d .text 0000000000000000 .text
0000000008048008 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 l df *ABS* 0000000000000000 ttext.c
0000000000000000 l df *ABS* 0000000000000000
0000000008048000 g O tinytext 0000000000000004 aa
00000000000000ff g F .text 0000000000000016 main

发现.text改变了,但是aa(.data)没有随.text而变,而是紧跟着tinytext的首地址

一个疑问,在开发过程中,可能板子的RAM地址比较低/高,那么我们要怎么改data和rodata字段使其符合内存的范围限制呢?

驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址的更多相关文章

  1. 驱动开发学习笔记. 0.02 基于EASYARM-IMX283 烧写uboot和linux系统

    驱动开发读书笔记. 0.02 基于EASYARM-IMX283 怎么烧写自己裁剪的linux内核?(非所有arm9通用) 手上有一块tq2440,但是不知道什么原因,没有办法烧boot进norflas ...

  2. 驱动开发学习笔记. 0.06 嵌入式linux视频开发之预备知识

    驱动开发读书笔记. 0.06  嵌入式linux视频开发之预备知识 由于毕业设计选择了嵌入式linux视频开发相关的项目,于是找了相关的资料,下面是一下预备知识 UVC : UVC,全称为:USB v ...

  3. 驱动开发学习笔记. 0.04 linux 2.6 platform device register 平台设备注册 1/2 共2篇

    驱动开发读书笔记. 0.04  linux 2.6 platform device register 平台设备注册  1/2 共2篇下面这段摘自 linux源码里面的文档 : Documentatio ...

  4. 驱动开发学习笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇

    驱动开发读书笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇 下面这段摘自 linux源码里面的文档 : 内核版本2.6.22Doc ...

  5. 驱动开发学习笔记. 0.01 配置arm-linux-gcc 交叉编译器

    驱动开发读书笔记. 0.01 配置arm-linux-gcc 交叉编译器 什么是gcc: 就像windows上的VS 工具,用来编译代码,具体请自己搜索相关资料 怎么用PC机的gcc 和 arm-li ...

  6. Android学习笔记(二)之异步加载图片

    最近在android开发中碰到比较棘手的问题,就是加载图片内存溢出.我开发的是一个新闻应用,应用中用到大量的图片,一个界面中可能会有上百张图片.开发android应用的朋友可能或多或少碰到加载图片内存 ...

  7. [PyTorch 学习笔记] 7.1 模型保存与加载

    本章代码: https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson7/model_save.py https://githu ...

  8. Linux驱动开发学习笔记(1):LINUX驱动版本的hello world

    1.关于目录    /lib/modules/2.6.9-42.ELsmp/build/   这个是内核源码所在的目录    一般使用这样的命令进入这个目录:cd /lib/modules/$(una ...

  9. Django 学习笔记(三) --- HTML 模版加载 css、js、img 静态文件

    人生苦短 ~ Tips:仅适用于 Python 3+(反正差别不大,py2 改改也能用).因为据 Python 之父 Guido van Rossum 说会在 2020 年停止对 Python 2 的 ...

随机推荐

  1. 【解决】SQL Server作业中Excel Application不能访问文件

    在通过SQL Server作业来实现定时任务时,出现如下错误: FullyQualifiedErrorId : ComMethodTargetInvocation使用“1”个参数调用“Add”时发生异 ...

  2. 学习indy组件之一idhttp的使用方法

    登录 注册 百度首页 新闻 网页 贴吧 知道 音乐 图片 视频 地图 百科 文库 经验 搜索答案我要提问 首页 分类 公社 知道行家 问医生 高质量问答 经验 个人中心手机知道开放平台   关于del ...

  3. petapoco存储过程

    db.ExecuteScalar<string>("exec P_GetCode @0,@1,@2,@3,@4,@5",); using (var db = new D ...

  4. sqlserver表分区

    参考:http://www.cnblogs.com/knowledgesea/p/3696912.html 及百度搜索sqlserver表分区 create partition function sg ...

  5. 思考力——提升企业竞争力的核心因素

    如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 · 思考力就是竞争力:在这个科技飞跃进步的时代,很多事物是我们未曾经历也难以预料的. ...

  6. 使用BigDecimal进行精确运算

    首先我们先来看如下代码示例: 1 public class Test_1 { 2 public static void main(String[] args) { 3 System.out.print ...

  7. linux mysql重装问题

    系统 :ubuntu16.04 使用apt-get命令安装mysql,启动时出错: can't connect to local mysql server through socket '/var/r ...

  8. AngularJS-chapter1-2-四大特性

    4大特性 MVC MVC实例  数据模型,控制器,视图 HelloAngular_MVC.html 图中的 ng-controller="HelloAngular"  定义了Hel ...

  9. 执行Python "/bin/usr/python: bad interpreter: No such file or directory" 错误

    今天在电脑上写了一个Python脚本,写好之后用ftp传上去,然后执行/var/www/cron.py,结果报错,/bin/usr/python: bad interpreter: No such f ...

  10. ORACLE常见数据类型详解

    1.字符类型 • CHAR:一个定长字符串,当位数不足自动用空格填充来达到其最大长度.如非NULL的CHAR(12)总是包含12字节信息.CHAR字段最多可以存储2,000字节的 信息. • VARC ...