重新分析: 加载地址 存储地址 链接地址 运行地址

重新分析: 加载地址  存储地址  链接地址  运行地址 


首先来说:我这几天,天天刷博客,去研究这个问题,其实讲透了也没什么。


1,运行地址<--->链接地址:他们两个是等价的,只是两种不同的说法。
2、加载地址<--->存储地址:他们两个是等价的,也是两种不同的说法。


其实有时候知道的越多,困扰也就越多,抛弃那些东西,我们来看:
还是很好理解的,什么是加载地址:说白了,就是从哪里拿数据代码放到内存,也就是你下载后放在了
flash的什么地方。这就是加载地址,对于pc来说应该是磁盘地址吧,(具体叫什么不知道,仅仅是推测)。
那什么是运行地址那?其实我一开始不曾想过运行地址的决定最开始竟然是由连接器决定的,但是反过来想想
也是对的,因为我们知道一个程序的各个段,以及内存的映射,从生成文件的时候就已经确定了,所以在内存中
的地址映射也就确定了,那么地址自然也就确定了,而且需要注意的是,生成的文件是有个头信息的,linux下是elf
windows下是PE,这些东西主要是为了操作系统在加载的时候,可以加载对各个段。但是现在我们没有操作系统
我们现在是裸机。我们想要运行一个程序,在连接器链接完一个程序的一些核心的东西地址已经确定了,(确定的原因是
连接器自己有一套地址规则)最为典型的就是
全局变量,地址是固定的,比如地址是0x 40008000,那么这个程序在下载到flash中进而从flash的地址加载到内存的
时候能否把这个全局变量的值加载在这个内存地址上,这就关键了,如果不能,那你这段代码执行的时候,必然出问题
找这个地址结果值不对,对于裸机来说,我们内存的地址似乎我们是可以掌控的,我们是明确的,我们的ram地址是多少
我们也是确定的,那好了,我们能不能就如我们心愿,把这个全局变量的地址就搞到对应的内存地址上哪?


其实,我们是可以明确的,首先来说,硬件是改不了的,那么我们只能够修改我们的代码了,我们把生成的段的地址
修改了,让他和我们的实际内存相匹配,那我们就ok了。而修改的这个过程叫做重定位,可以用命令 -Ttetx=0x40009000
也可以写个脚本实现。然后我们用 go 40009000就可以运行了。当我说我这句你是不是有蒙蔽了!对,我讲的是裸机程序
倘若谈真正意义上的裸机程序,那就是bootloader是如何运行的,其实一上电,arm来说必然是0x00000000处运行,但是
这个0x00000000处是什么那,时候从来都是rom,当然也有ram,各个开发板不一样,其实这俩种东西都会让你产生问题
rom把,不是说代码不能在ROM中运行吗?其实不然,是不能写数据,可以写条跳转指令啊!对于ram来说,一上电,谁把数据
写入ram其实是靠硬件的一些控制器来实现的,一上电将数据加载到内存,然后运行。


但是在uboot下这是靠lds链接脚本实现。当然如果你外接-Ttetx=0x40009000,那么以外部为准。
回到我们的问题:我们应该明确的是程序一开始是在rom即使加载到内存也仅仅是几k,放到这几k的代码往往是位置无关的代码
然后用这些代码,来初始化真正的大内存,(外接内存)然后这时候就需要我们在链接的时候重定向的代码,放到和链接地址
一样的地方,然后运行。













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值