前言
SOC原型验证,编译程序的时候遇到不支持除法的问题。网上没有一个方便的解决方法,我利用sed替换实现了一个好一点的方法。
文章以遇到问题的顺序来记录。
问题1:不支持除法
这个问题的乐音还是比较简单的,网上讲的很清楚,arm是精简指令集,本身不支持除法需要调用第三方的库软件实现。这里调用lgcc的库,需要再连接的时候加上,如下图所示。
这里-l 后面加库名gcc
库可以到gcc的官网上,找架构相同的版本下载,也可以再自己编译环境下搜索一下,有时就藏在其他>目录下面,拷贝过去就行了。
问题2:bl跳转问题
上面加上库之后,还是有问题。提示
relocation truncated to fit:
这个可以通过编译的汇编文件查看,可以看到汇编文件里面调用__umodsi3和__udivsi3使用的是bl指令。bl指令跳转的范围很小。这里需要使用ldr指令代替跳转。
替换前:bl __umodsi3
替换后:ldr pc, =__umodsi3
这个可以使用sed命令进行批量替换。
sed -i 's/bl\s__umodsi3/ldr\tpc, =__umodsi3/' 汇编文件名
sed -i 's/bl\s__udivsi3/ldr\tpc, =__udivsi3/' 汇编文件名
问题3:no memory region specified for
上面改完单文件已经可以编译了。这个问题和我的链接脚本有关。和编译除法应该没有关系。
编译多文件的时候,使用include把其他的c文件都include进来。然后进行编译。报错
no memory region specified for
这个设计到链接脚本,原因是没有给编译的.o文件里面的text字段设置空间。
贴上来我的链接脚本:
类似的问题应该有一个共同的解决方法:你把提示缺少的字段加到链接脚本里面分配空间即可。
可以用*匹配多个文件。