最初的设想是想用uboot的loadb命令来调试自己移植的uboot,发现串口没显示,当时就晕了 就不想再动了,原因可想而知是各种各样的,难~~~ 但再想想是不是思路有问题,就打算写个裸C来试下loadb命令。
整个程序就是实现个流水灯(也就只有三个LED),就叫做led.c吧,编译成led.o,再用arm-elf-objcopy成led.bin,通过串口,用uboot命令loadb 0x0c008000 用超级终端传送一下,(很快,一下而过)发现板子没反应,(又晕了)只有找google了(还是推荐google,百度还是差点)发现还要链接,那就arm-elf-ld -Ttext 0x0c008000 -nostdinc -o led.elf led.o(不是很懂为什么要加-nostdinc 然道是为了帮ld省事,不要去找stdinc??)。再次loadb 发现板上的灯还是没动静()这可杂办呢~~~
再次使出google大法,再看看自己的led.c~~~~~(时间很长)
终于找到了一点有用的:“对于裸机C程序,入口函数应该放在文件最前面”
然道我的灯不动就是因为在entry()之前写了一个delay()????
那就试着改一下吧,所有其他函数都写在entry()之后,再次arm-elf-gcc arm-elf-as arm-elf-ld arm-elf-objcopy~~(各种难啊~~)最后loadb 0x0c00800~~~~~~~
终于是见到板上的LED如程序所写一样的动起来了~~(激动啊)
激动之后再想想,觉的所谓的裸C程序,入口函数应该在文件最前面 这一点甚是不懂啊,再次请教google大叔,哎,发现有关的太少了,看样子是没多少人研究这个了~~~
突然想到arm-elf-readelf这个东西,还是用用吧,打开led.elf看看,于是在arm-elf-readelf -a led.elf作用下,显示了一大堆,当时就眼花了,怕了~~~
还是慢慢来吧,一步一步来,先arm-elf-readelf -h led.elf
还是能看懂的,非常简单的几个english word 再次arm-elf-readelf -s led.elf
感觉自己要的东西出现了~~~~
出现了类似表单的文本,不懂头几个单词的意思()却在下面发现了entry ~~
还在同一行看到了0c008000 应该是说在0x0c008000这个地方有一个entry 哈哈,这个我懂啊,所谓的程序入口函数嘛,我的程序就是要在0x0c008000处开始运行啊
于是我再改回我原来的led.c,把delay()放在entry()前面,再次arm-elf-readelf -s led.elf,发现
在0c00800 一行上对应的是 .gcc2_compiled 而entry这一行对应的地址却是0c00802c
哎,这才总算在猜测+测试中发现所谓的裸C程序入口函数为什么要放在最前面了(只是猜测没人告诉我why)裸C程序里的函数放置地址是按函数实现的地址来放置的 就是说在内存中函数的放置地址顺序与在文件中的实现顺序是对应的~~ 而非裸C程序,甚至只要加了个符号链接的话,在内存中的执行地址与程序文本中的实现地址是无关的~~
~~~由此牵扯出的一大堆问题怕是难以一下解决的了,哎 难~~~
路漫漫其修远兮~~~~~~~
上一篇:uboot之relocate代码的深入理解
下一篇:分享一年的程序调试经验
推荐阅读最新更新时间:2024-03-16 14:26