龙芯开源社区

 找回密码
 注册新用户(newuser)
查看: 1427|回复: 8

龙芯1B,cache问题求助

[复制链接]
发表于 2017-3-24 12:27:54 | 显示全部楼层 |阅读模式
编译运行一个应用系统,龙芯1B上跑,在一个汇编文件中,发现一个 .extern abcInfo 的一个声明,而本汇编文件也没有用到,于是删除这个声明,重编译后运行失败,不删除就完全正常启动。abcInfo是一个结构体变量,是否初始化都没关系,data/bss段没影响。 反正就是删除一行垃圾代码板子就起不来了。 经过大量调试,发现4点:
1. 有无 extern abcInfo ,对于kernel_asm.o 的objdump -D的反汇编,指令是完全一样的,没有任何区别,一个字节也不差。 而readelf -a 输出的结果,形式上有较多区别,变量偏移量不同,但实际也没有本质区别。

2. 出问题的函数,总是在 kernel_asm.s 文件最后几个汇编函数,比如最后的_thread_stack_set移动到文件开始,则可以正常运行通过,而接下来的新最后的函数 _thread_load_context就会出错。 如果在文件最后定义两个简单的汇编新函数,则这新函数调用时,也会产生死机现象。第一次看到过移动源代码位置,会影响板子启动的现象!

3. 调试打印的信息,不完全可信。比如 _thread_stack_set 函数移到文件的开头部分,则这个函数可以执行下去,但是提前用物理串口打印_thread_stack_set地址内的内容,与反汇编的指令,也不一致。既然能运行,指令不可能出错。猜测指令总线/cache和数据总线/cache不相同的缘故。

4. PMON引导本系统,PMON保持不变。 本系统最早初始化阶段加了一些cache的操作,也没效果。我认为还是cache哪里没设对,请高手帮忙!
 楼主| 发表于 2017-3-27 10:58:03 | 显示全部楼层
龙芯1B最大各有4路16KB的指令cache和数据cache。读config寄存器确定本板子只用了一半:
I-cache:  .lineSize = 32, .ways=2, .sets=128, .wayStep=4096. Total=0x2000 (8KB)
D-cache: .lineSize = 32, .ways=2, .sets=128, .wayStep=4096. Total=0x2000 (8KB)

在系统启动开始,和出问题的函数调用之前,分别把cache 清理一下,都没有任何改观,现象依旧。
清理指令cache用的 Index_Invalidate_I_Ls1x, 即 cache Index_Invalidate_I_Ls1x, 0(a0)
清理数据cache用的 Index_Writeback_Inv_D_Ls1x,即 cache Index_Writeback_Inv_D_Ls1x, 0(a0)
a0寄存器传入虚拟地址
 楼主| 发表于 2017-3-28 08:19:01 | 显示全部楼层
经调试证据明显:
0xa03d2b60: 0x40028000  0x00000040 0x00000040 0x03e00008  //正确的文本段指令
0x803d2b60: 0x800cd7d0  0x803c8528 0x30323033 0x303d2c14   //cache中的内容不对

cache 0, 0(a0) 参数传递遍历8KB大小的区域刷指令cache
HAZARD_CACHE

cache 1, 0(a0) 参数传递遍历8KB大小的区域刷数据cache
HAZARD_CACHE
两个cache都刷了,也不能达到一致。 刷cache方法不对?
 楼主| 发表于 2017-4-18 14:34:30 | 显示全部楼层
被证明是一个 gp 寄存器初始化的值,对齐问题。链接脚本定义_gp 的值,要从16字节对齐,改成32字节对齐。game over
 楼主| 发表于 2017-4-18 14:40:13 | 显示全部楼层
readelf 查看 elf文件的 small data 段对齐值,链接脚本查看 _gp 对齐值。 要一致
 楼主| 发表于 2017-4-19 17:56:30 | 显示全部楼层
本帖最后由 Wiener 于 2017-4-19 17:58 编辑

今日又发现最直接最根本的原因:汇编代码中设置sp寄存器的值搞错了,堆栈指向了代码段里,所以是随着函数的调用过程而发生的指令内存被改写的情况。 把汇编的第一个函数,用特殊段指示,然后连接器把这个特殊段安排成第一个指令,然后sp从这第一个指令往下使用,使之永不破坏文本段,则解决。

结贴。
发表于 2017-4-20 09:25:29 | 显示全部楼层
赞赏楼主能分享结论的精神。
 楼主| 发表于 2017-4-24 15:58:15 | 显示全部楼层
本帖最后由 Wiener 于 2017-4-24 16:03 编辑

都知道堆栈溢出的副作用,不绞尽脑汁的调试一次掉层皮,就无法记忆深刻。开始总是找cache的问题,因为用EJTAG读出的内存值也与期望值不一致,认为是板上钉钉的问题了,仔细核对了cache汇编指令,刷cache也没有问题。预感到方向错了,但不知找哪里。现在回想内存值被改的,有特征性,像一些地址,一些字符常量,不是毫无规律的杂乱无章,就是没猜测到这个方向,实际应该早点想到
发表于 2017-4-25 12:17:50 | 显示全部楼层
顶!赞赏具有原创和研究精神的人!

本版积分规则

小黑屋|手机版|Archiver|Lemote Inc.  

GMT+8, 2019-6-20 04:53 , Processed in 0.193134 second(s), 19 queries .

快速回复 返回顶部 返回列表