2009年3月31日19:38:10
昨天遇到一个比较fucking的问题,arm-elf-gcc生成elf文件之后,会在main函数之前添加一些初始化代码,并把svc下的堆栈指针修改成0x08000000。这是我们所不希望的!因为在程序的初始化代码startup.s里初始化svc的堆栈指针为0x001ffffc,而程序进入main函数之后,堆栈到了0x08000000处!在连接脚本里指定了stack空间但是好像没用。逐步跟踪程序运行,发现堆栈指针是在_mainCRTStartup中修改的。如下:
00012330 <_mainCRTStartup>: 12330: e3a00016 mov r0, #22 ; 0x16 12334: e28f10e4 add r1, pc, #228 ; 0xe4 12338: ef123456 swi 0x00123456 1233c: e59f00dc ldr r0, [pc, #220] ; 12420 <_mainCRTStartup+0xf0> 12340: e590d008 ldr sp, [r0, #8] ; 12344: e590a00c ldr sl, [r0, #12] 12348: e28aac01 add sl, sl, #256 ; 0x100 1234c: e3a01000 mov r1, #0 ; 0x0
|
如果把第12340处的指令替换成nop不就可以防止修改sp了吗,于是用ultraedit打开arm-elf-gcc生成的elf文件,查找机器码e590d008,将其替换成nop指令的机器码e1a00000(就是mov r0 r0),成功运行,sp指针没被修改(*_*)!问题虽然解决,但不能每个benchmark都去修改机器码。仔细考虑一下,其实这段代码是连接的crt0.o,在arm-elf/lib下面。将crt0.o中的机器码替换掉不就可以了吗,按照同样的方法将crt0.o里的e590d008替换成e1a00000,重新编译了几个benchmark后成功运行,搞定。
看一下elf文件的反汇编:
12408: eb0000c4 bl 12720 <atexit> 1240c: eb00274b bl 1c140 <_init> 12410: e1a00004 mov r0, r4 12414: e1a01005 mov r1, r5 12418: eb000097 bl 1267c <main> 1241c: eb0000e2 bl 127ac <exit>
|
看到atexit,main,和exit了吧,这段代码在crt0.o里,可见crt0.s的重要性!
2009年4月2日9:19:40
昨天遇到三个棘手的问题:
1. time slot 如何准确定时;
2. cycle 和 clock 之间的关系;
3. svc stack 为何搬运到tcm会出现问题。
2009年4月10日10:02:35
又过了一个星期,修复了很多小问题,现在的情况是:
1. stack 和 heap的搬运都没问题了,问题出在模型没有修改完整,在exception.cc中,_sys_read, _sys_wright等函数里的read,wright等要修改成readwithmmu,wrightwithmmu等。
2.为了准确定时timer,采用了如下措施:
a. 在每个slot中更正timer定时周期,周期表放在0x11100里,每个周期占1个word。第一次timer固定为5000,000个clock,后面的依次读取timer周期表中的周期更正;
b. 以前页的搬运放在页错异常里,现在放在timer里做,这样每次timer来了之后除了修改定时周期外,还要修改页表和DMA搬运页到tcm或从tcm搬回SDRAM。
下面介绍一下更正timer周期的方法:
1. timer周期为什么要更正呢?
这与我们的profile过程有关:首先模型裸跑一遍,得到每个slot中的miss和hit信息, 然后在MATLAB中求出每个slot的conflict graph,根据conflict graph求解出每个slot应该搬运到tcm中的页。问题就出在这里,当上一个slot中选中的page搬运到tcm中后,程序的执行时间已经改变了(正常的话应该缩短),所以如果定时周期与profile时的slot周期相等的话,必然会导致下一个slot搬运时间的错位(延迟了)。经过多个slot后,错位原来约严重,以至于导致本次搬运的page可能是在上个实际的slot里应该搬运的!所以必须更正timer周期!
2. timer周期如何更正
既然每个slot的时间在进行页搬运后有所改变,所以timer周期不能定为等长的,必须在每个slot搬运后对timer周期进行修正。修正的过程是这样的:从第一个slot开始,当timer中断到来后,先把需要搬入tcm的页搬入tcm中,在下一个slot开始处,把tcm清空,程序执行完后的clock与上一次程序执行的clock之差就是该slot的performance收益,相应的slot周期为原周期减去本次slot的收益,这样反复遍历,最终得到timer的周期表。
2009年4月13日18:35:36
添加功耗模型
阅读(2170) | 评论(0) | 转发(0) |