Chinaunix首页 | 论坛 | 博客

  • 博客访问: 480906
  • 博文数量: 86
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 878
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-06 14:11
文章分类

全部博文(86)

文章存档

2010年(12)

2009年(60)

2008年(14)

我的朋友

分类: C/C++

2009-03-31 20:04:32

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) |
给主人留下些什么吧!~~