u-boot相关powerpc处理器
大家好,又来请教大家了。
之前咨询过大家关于powerpc的一些问题,现在我们板子用uboot引导起来了,我们裁剪了u-boot。
在之后应用编程发现一个问题,用汇编语言编写的函数,访问一个已经初始化的全局变量,全局变量在之后在一个C代码函数里修改过,在汇编函数里读取值发现全局变量的值还是初始化的。
过程如下:
unsigned long globala=111;//全局变量
在一个C函数里:
void A()
{
...
修改globala =200;
...
}
在一个B汇编函数里:
读取修改的全局变量:
.globl global
global:
mflr r27
lis r3,globala@ha
lwz r3,globala@l(r3)
bl printgl //打印globala的值,发现还是111,而不是200,
mtlr r27
blr
我们认为和got全局偏移量表有关,是不是全局变量放在偏移量表里面了,所以没法访问:
然后汇编修改如下:
lis r3,globala@got@ha
lwz r3,globala@got@l(r3)
发现还是111.而不是200??
想请教下大家。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
你这个代码是在rom里面还是ram里面运行的呢?
惨了,我发现freescale的基于e300内核的mpc8313开发板。
在boot起来时,CPU片选nor flash(地址为0xfe000000,ram的地址为0x0),在flash里启动,然后重定位到ram里进行,在ram里起来后,ram地址为0x0,flash还是为0xfe000000,这就导致了程序编译和运行的地址不一样,导致访问全局变量时,地址还是flash的地址,除非在函数里,申请临时变量来获取全局变量的地址(编译器解决了这个问题),直接在汇编代码里获取全局变量的值和地址还是在flash里的,没有取到ram里的。我们不知道怎么解决全局变量地址问题?这和arm不一样,arm起来时,flash是0x0,内存是0x50000000,重定位后,又把ram映射为0x0,flash映射为0x50000000,不会使同一个变量有2个地址。
各位大侠,有什么高见啊?
linux怎么做的~
关键在你的 A 函数是在哪个位置调用的,如果是在重定位初始化之后,变量的地址就应该进行修正,也就是说赋值的语句要加上偏移的。
你的具体需求是啥?感觉你的做法很怪异。
emulator+breakpoint+watch+step
是啊,重定位初始化之后,变量的地址就应该进行修正,也就是说赋值的语句要加上偏移的。
但是,在u-boot起来后,不可能在写应用程序时,每访问一个全局变量都要手工加上偏移地址吧,想知道,在start.S里或在编译过程中,做些什么工作,使得重定位前和之后,地址一致?
我们需求是,在u-boot起来后,加上自己的调度程序,系统保护及mmu,然后自己在此基础上写应用程序,也就是说把u-boot和我们自己的应用绑在一起。不是用boot来引导linux。
经验告诉我,发生"灵异事件"99%以上来源于自己的想当然,每个人,包括我,经常会遇到这种事.
先调试看看吧.
确认,这个变量你真的可以修改,你确认修改的是RAM里的数据?你用的是某种DRAM?你确认初始化过了?代码真的按你想象的执行的?.......等等,诸如此类
实在不理解版主的回答??
这不是什么灵异事件,我们用codewarrier仿真器查了,我是想问大家,当重定位前,和重定位后,数据或代码地址不一致怎么解决?
除非mpc8313板子有额外的硬件,把从ram启动之前,把flash地址0xfe000000就定为0x0。
我想知道linux在u-boot起来后,怎么解决这个问题的~
召唤Cyberman.Wu 达人,最近还逛论坛吗?
在board_init_f最后会有relocate_code操作,这个地方会把Rom中的代码、数据搬移到Ram中,相关单板信息、堆栈等都会一并搬到RAM,然后运行board_init_r。
所有u-boot分为两段,如果两段运行(Run in ROM/RAM)需要有数据共享,就需要重定位或者通过relocate_code放方式把数据拷贝过去。
RAM/ROM之间一般不共享全局变量。
把flash的那个全局变量所在的地址块映射到程序需要访问的地址上(虚拟地址),打开MMU