我的第一个嵌入式程序诞生过程

2019-07-12 18:06发布

我的第一个嵌入式程序诞生过程

说明:本人以前一直是从事linux和windows下应用程序开发的,因为兴趣最近开始从事嵌入式开发。以下是
我的第一个嵌入式程序诞生的过程,呵呵,值得记下一笔。
平台:Redhat FC6 + Sigma Designs 862XL


任务是将我写的ntp对时客户端移植到目标板上,前面我已经在linux下用gcc编译并在宿主机上运行通过的。
第一步,想当然的认为用交叉编译器编译就行了,此处的交叉编译器为arm-elf-gcc,于是执行:
  arm-elf-gcc -c ntpclient.c  # 通过
  arm-elf-gcc -o ntpclient ntpclient.o  # 通过

呵呵,太easy了吧,这么容易就编译并链接好了可执行程序!?于是兴奋的跑到板子上mount nfs系统,运行

  ./ntpclient
出来以下错误:
BINFMT_FLAT: bad magic/rev (0x1010161, need 0x4)
BINFMT_FLAT: bad magic/rev (0x1010161, need 0x4)
ntpclient: applet not found

看不懂这些错误,想想是不是因为我里面用到了网络编程,板子需要额外链接网络库才行?那好,咱就从最
基本的"hello world"开始吧。
马上动手写了个hello.c,编译执行:
  arm-elf-gcc -o hello hello.c
  ./hello
还是出现错误:
BINFMT_FLAT: bad magic/rev (0x1010161, need 0x4)
BINFMT_FLAT: bad magic/rev (0x1010161, need 0x4)
hello: applet not found

看来不是链接库的问题,事情往往没有自己想象的那么简单啊!马上到网上查了一下资料,终于弄明白原来
板子使用的是elf的扁平(flat)格式,编译时需要使用-elf2flt选项生成flat格式的可执行文件。
顺便提一下:elf为Linux系统所采用的通用文件格式。flat:扁平格式。elf文件有很大的头文件,flat格式
对文件头和一些段信息做了简化,可执行程序小,适于嵌入式系统。
执行如下编译:
  arm-elf-gcc -o hello -elf2flt hello.c

奇怪,怎么生成了两个绿 {MOD}(可执行)的文件:hello和hello.gdb,我该执行哪个呢?
  ./hello
不行,报错:./hello: cannot execute
  ./hello.gdb
还是不行,报错:./hello.gdb: cannot execute

别气馁,baidu、google一下"cannot execute",网络真好真方便,什么事不懂都可以问它,而且完全免费(
当然,上网费还是要出的!),我现在坐个公车、生个小病、做个小菜都喜欢上网搜一下。
"cannot execute"太宽泛了,没找到什么有价值的东西。换换手气吧,搜了半天"arm-elf-gcc .gdb",差不
多弄明白.gdb是干嘛的了,原来是可以使用arm-elf-gdb来调试的啊,呵呵。

可是,还是没找到为什么不能执行的原因啊,郁闷!其实这之前我已经想过了执行权限的问题。
板上执行:
  whoami  # 输出root
  ls -l hello  # 权限位为-rwxrw-rw-
是对的啊,此时我忽视了即使通过nfs mount过来后,该文件的所有者还是ly!

实在不行了,去蹲蹲坑、放放水吧,呵呵,这招对我挺有效的!回来之后不知道怎么一发狠就来了这招:
  chmod 777 hello
  ./hello
我靠,成功了!hello world! 久违了,那激动劲差不多就跟咱当初用TC2.0 hello world出来一样!
回过头一想,不就是个权限设置的问题嘛,晕倒!害得我瞎折腾了半天!权限害死人啊!

这下简单了吧,动手来移植ntpclient了:
  arm-elf-gcc -o ntpclient -elf2flt ntpclient.c
  chmod 755 ntpclient (呵呵,没必要再777了吧!)
换到板子上运行:
  ./ntpclient
出错:gethostbyname: Network is unreachable

这个好办,不就是网络不行嘛,咨询了下网管,ifconfig改了下IP,再运行:
  ./ntpclient
还是出错:gethostbyname: Network is unreachable

晕倒,我不都按照网管分配的IP设置了吗,怎么还是不行!拉个同事来帮我分析下网络,呵呵,结果发现是

ifconfig的时候居然把路由给清掉了,那还能上网,添加路由:
  route add default gw xx.xx.xx.xxx
搞定!