riscv-gcc工具编译firmware进行仿真问题总结
创始人
2024-04-03 01:47:49

Q1 riscv裸机编程undefined reference to `_memcpy` :c代码中数组长度超过16,并在定义时做初始化,编译报错问题,

Q2 全局变量初始化问题

Q3 riscv裸机编程undefined reference to `_memcpy` :c代码中字符数组长度超过16,并在定义时做初始化,编译报错问题.

Q4 字符串常量初始化问题。

A.Q1,QQ3两个问题使用gcc三级优化选项解决

B.Q2,Q4两个问题是,反汇编时,objump,只选取了.text段的代码(使用的的是-d,只disassembly了.text段),而应该将.rodata段的也进行反汇编,应该使用-D将所有段进行反汇编。

objdump -d app.elf    //对包含机器指令的段进行反汇编

objdump -D app.elf    //-D 与 -d 类似,但对所有段进行反汇编

 

Q1.现象c代码中数组长度超过16,并在定义时做初始化,链接时报错undefined reference to `_memcpy`,如果长的字符串也是一样的。

代码:

报错,推测(对编译不是特别了解)是由于数组过程,直接初始化,会使得编译器调用memcpy这个函数(可能是直接用汇编写的函数,可能是编译器自身做的优化,如果数组长度比较小,那么可以直接赋值,如果长的化,编译器就会优化出来调用这个memcpy这个函数,如果你没有定义就会报错)

但是系统或者工具链里面没有这个函数,所以,编译完成后,在链接时,就会报错(因为链接器找不到这个函数):

如果定义成16长度的数组:

编译结果,汇编代码中会一个个去初始化数组的值。;

所以数组过长,避免这个错误的方式:这里采用的方法是,可以在c代码里面使用循环来初始化。或者使用一个个手动初始化。

Q2.另外全局变量定义后初始化时也不成功。

所以全局变量单独使用了一个函数来做初始化(一种做法)。

注意更新了一下链接脚本。

比如有如下代码:

func.c编译结果,如下,可以看见全局变量的初始化值被放入了data段(.sdata包含其中):

注意我把链接脚本做了修改,主要修改时是ram段的地址,因为若是原来的地址(见Q4中的链接脚本中的地址段),仿真时访问的是fffffff地址而不是5208000:

但是, 我仿真时没有,并没有读到初始化的值,读到是0,说明全局变量没有被初始化。但是从链接结果来看,全局变量的初始值是放入data段的。

仿真波形如下。可以看到5b000000读出来的值为X,说明并没有被初始化:

Q3.另外长字符串常量也编译不成功(这个和Q1是同一个问题)。

比如代码:

编译结果中可以看到,也是调用memcpy这个函数,所以链接时也会报错:

Q4.字符串常量的另外一个问题:

当我把字符串长度减少,可能是编译觉得不用优化,就没有调用memcpy这个函数。比如下面这个代码:

编译结果,注意这种情况下,没有调用memcpy,并且常量也没有放在rodata段。程序可以正常使用,也可以正常连接:

但是,如果我在一个函数的参数中使用了一个字符串常量.比如:

此时编译结果,会将这printstr("abcd\n")中所使用的字符串常量放在.rodata段:

连接结果的map中显示,的确存在firmware的常量连接到了rodata段(但是我实际去跑代码时这段地址仍然没有被初始化为X态):

rodata段地址,见下面的链接脚本:

波形如下,当去读取0xa000_0000这个rodata地址时,读出来的值是x.

所以没法这样使用字符串常量。

解决:

(一)GCC的三级优化。(解决Q1和Q3)

GNU编译器提供-O选项供程序优化使用:

-O 提供基础级别的优化

-O2 提供更加高级的代码优化,会占用更长的编译时间

-O3 提供最高级的代码优化

-O4 不优化,这是默认值

上面Q1,3这两个问题,会得到解决。编译器不会再调用memcpy函数。

(二)反汇编生成firmware时,只使用了.text段,其他段并没有使用。

如下所示,第31行,-d这个选项只会对对包含机器指令的段进行反汇编

比如Q2这个问题。使用riscv32-bst-elf-objdump -d isp_firmware得到的结果如下,结果中只对.text进行了disassembly。这样在

第35-36句时只会使用生成,.text段相关的地址和数据。

如果使用-D,就会包含所有段的disassembly:

按照-d,生成的最终仿真使用的文件coreisp.elf.txt如下,可以看见最终firmware中并没有5b00_0000地址段。

Q4这个问题也是一样的,并没有rodata段没有写入到最终firmware中。

需要修改地方,0.对于data段(ram)地址范围也需要修改下。

                        1.makefile的31行改为-D。 这样会把所有段都包含进结果。

                        2.修改脚本od2txt.py脚本从包含的所有段的结果中筛选出需要的段。(除了.text段外还有,比如Q4的rodata段和Q2的.data(其中包含.sdata)段)

                        原来的:

                        

                        修改后的:

                        

修改后例子:

编译之后再使用objdump -D反汇编的得到:

   

然后使用修改后od2txt得到下面结果,最后几行是sdata和rodata的值,和代码是对应上的:

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...