虽然自2012年9月开始就做嵌入式了,但感觉自己一直在打酱油,首先玩的loongson的平台的片子(玩过的人都懂的),其次是公司招我进去的目标只是为了验证公司做的硬件是没问题的,整个方案基本就是按开发板做的,所以自己基本没有什么可以改,最多就是做几个IIC的小芯片驱动,基本就是编译下程序,看看数据对不对。
时间就快过去一年了,尝试着去面试了几家公司,回来深受打击:没有做上层的经验,说做底层,可是bootload都没玩过,不清楚bootload的启动流程,没有分析过启动代码,没有调试过内存芯片,没有写过裸机代码,只是知道内核下简单驱动的框架,但没做过音视频驱动,没有做过USB……
出去面试一遭,才知道自己一年内打酱油打的多么的彻底,所以痛定思痛,决定从0开始(做了一年的好处是,对概念性的东西不陌生),从最基本的uboot开始,用了几天时间,看完了start.S,了解了大致的启动流程,同时也对比了loongson的pmon启动代码,其实发现流程都是差不多的。
然后,就想在uboot下搭建裸机开发环境,首先从最基本的“helloworld”开始,
开始的时候代码直接写成:
#include<stdlib.h>
int main(int argc, char **argv)
{
printf("Helloworld!\n");
}
直接就是编译错误,上网一查:原来uboot下没有库函数可用 所以不可以通过调用lib库的标准printf函数实现打印输出,但变相通过uboot本身实现的printf函数 利用函数指针进行printf函数调用,于是乎参考了网上的代码:
void (*show)(char *, ...);
int main(int argc, char **argv)
{
show = 0x33f9303c;
show("Helloworld!\n");
}
虽说网上说“show = 0x33f9303c;”是通过查看uboot的System.map得到的 各个版本可能不同,但并不是很明白,先不管,直接编译 hello.bin:hello.o
arm-linux-ld -Ttext 0x30000000 hello.o -o hello.elf
arm-linux-objcopy -O binary hello.elf hello.bin
arm-linux-objdump -d hello.elf > hello.dls
hello.o:hello.c
arm-linux-gcc -c hello.c -o hello.o
clean:
rm hello.bin hello.o hello.elf hello.dls
编完将生成的bin文件放到tftp文件夹,在uboot下用tftp下载到0x30000000处(tftp 30000000 hello.bin),却运行不起来,自己也不知道原因,在网上找了一阵,却也只有那几篇文章,也没找出原因,于是纠结了几天,今天去深圳湾骑行50公里回来,也许锻炼出汗后会神清气爽,看东西都比较精神,再上网继续找原因,突然发现了原因:原来“show = xxxxxx;”中的xxxxxx是指uboot的System.map中的printf的地址,比如我的版本的地址是0x33f91708,OK,编译下载,运行一切如常了。
也许文内写的东西很简单,但是要是开始玩u-boot,且周围没有交流的人的情况下,这两个细节还是要花时间去解决的:show的地址、arm-linux-ld -Ttext 0x30000000 hello.o -o hello.elf中的链接地址要和u-boot的中下载地址一致。