1.裸机实验之SD卡下载
背景:一般来说,用USB下载来调试比较方便,但是有时候电脑使用dnw会频繁的蓝屏,这时候用SD卡下载调试是不错选择
从SD卡启动会先从iNand(SD0)启动执行,当iNand启动做校验和失败时才会转为启动SD2.而做裸机实验时是通过SD2来提供裸机程序镜像的,因此需要先破坏内部iNand的uboot才可以强迫开发板从SD2启动去执行我们的裸机程序。
在uboot底下擦出uboot: movi write u-boot 0x30000000
SD卡下载失败,但不影响后面的实验-使用dnw工具下载裸机程序
2.安装交叉工具编译工具链
linux安装软件的三种方式:
- 在线安装,譬如apt-get install vim 来安装vim软件
- 自己下载安装包来安装。缺点是不知道此安装包是否与安装的系统是否匹配。
- 最装逼的一种方式,就是源代码安装。
安装交叉编译工具链(arm-linux-gcc)实际采用第二种方式
工具链选择原则:和使用的目标平台(给哪款SOC 编程)尽量去匹配。
-----------从本节开始需使用虚拟机linux系统进行----------------
交叉工具编译链的安装:
- 将安装包从windows弄到linux下,用共享文件夹。也可以用smaba,cuteftp等.
通常linux下的系统下文件放置的一般定义:
譬如: /bin 目录放置一些系统自带的用户使用的应用程序
/sbin目录下存放的是系统自带的系统管理方面的应用程序
/usr 目录下一班安装我们用户安装的软件,安装arm-linux-gcc,就在/usr/local/底下创建一个arm文件夹
安装测试
到真正的应用程序的安装目录下即 /usr/local/arm/arm-2009q3/bin 下执行命令: arm-linux-gcc -v 然后在一长串输出后会显示版本号,即安装成功。
缺陷是在使用时执行此程序太麻烦,因为前面输入的太多(程序路径+命令),所以还需要再次整改:
- 环境变量的意义:操作系统的全局变量。 每一个环境变量对操作系统来说都是唯一的,名字和所代表的意义都是唯一的。linux系统可以有很多个环境变量。其中一部分是linux系统自带的,还有一些我们自己来扩充的。我们涉及的一个环境变量是PATH。 PATH 这个环境变量是系统自带的,它的含义就是系统在查找可执行程序时会搜索的路径范围。
将工具链导出到环境变量
ExportPATH=/usr/local/arm/arm-2009q3/bin :$PATH
现在就可以在任何地方执行命令而不需要在指明路径。
缺点是这个命令只能在一个终端生效,如果打开另一个终端,就不会生效,这样就会导致每次打开终端都需要再输入此命令,因为其他终端并未执行过这个命令。
解决方案:
Cd /root/ ls -a
找到.brach
Vi .bashrc
将命令添加到里面
原理是每次打开终端时这个文件都会执行一次,所以将命令添加到里面,每次打开是时就可以自动执行了。
需要注意的是导出环境变量是在当前用户,如果你登陆是在其他用户下是没用的。
- 为工具链创建arm-linux-xxx符号链接
ln arm-none-linux-gnueabi-addr2line -sarm-linux-addr2line符号链接命令
由于命令过多可以使用脚本来执行这些
细节注意:在windows下编辑的文本与在linux下执行的文本格式的不一致容易出现问题,所以最好在linux环境下编写脚本,或者在windows下编写好后,把文本再在vi下打开一次保存,这样就同一文本格式了。
3.Makefile 大侠隆重登场
- 为什么需要Makefile是用来管理工程的
在一个正式的软件项目中,由很多个.c和.h文件构成,此时如果直接在命令行编译,就会像这样:gcc a.c b.c c.c e.c -o exe 这样输入很麻烦,严重影响工作效率
基本使用:
thouch makefile
vi makefile
all:
gcc a.c -o exe
wq
执行:
make
- Makefile 中的一些基本概念
目标:目标定格写,后面是冒号(冒号后面是依赖)
依赖:用来产生目标的原材料
命令:命令前面一定是Tab,不能是定格,也不能多个空格。命令就是要生成那个目标需要的动作。
- Makefile的基本工作原理
- 当我们执行make xx 的时候,Makefile会自动执行这个目标下面的命令语句。
- 当我们make xx的时候,是否执行命令是取决于依赖的。依赖如果成立就会执行命令,否则不执行,比如已经执行了make,然后在执行,make是不会再次执行的,他会提示你当前的目标文件是最新的,除非依赖文件有所变动。
- 当我们直接执行make 和make+第一个目标 的结果是一样的,即第一个目标就是默认目标。
- ARM裸机用到的Makefile介绍
- 进一步学习Makefile的资料
学习Makefile的思路:先学会基本概念和应用,先理解Makefile的概念和使用方法、工作原理。先自己会写简单的Makefile来管理工程,还可以学习本书《跟我一起学Makefile 》 作者:陈浩
4.mkv210_image.c文件详解
一般裸机程序中的Makefile是把程序的编译和链接过程分开的。
平时我们用 gcc a.c -o exe 这种方式来编译时,实际上是把编译和链接过程一步完成的,在内部实际上编译和链接永远是分开独立进行的 ,编译要使用编译器gcc,链接要使用链接器ld
链接器得到led.elf 其实就是我们的可执行程序,如果在操作系统下,这个led.elf就可以执行了,,但是在嵌入式裸机中我们需要的是可以烧写的文件(可烧写的文件就叫镜像image),因此我们需要用这个led.elf为原料来制作镜像,制作工具是交叉编译工具链中的arm-linux-objcopy
我们使用arm-linux-objump工具进行反编译(反汇编),反编译其实就是把编译后的elf格式的可执行程序给反过来的到对应的汇编程序,得到她的汇编代码。我们使用反汇编主要是用来学习。
mkv210_image.c 这个程序其实最终不是在开发板上执行的,而是在主机linux(就是执行make对整个项目进行编译的那个机器)中执行的,因此编译这个程序用gcc而不是用arm-linux-gcc 这个.c编译后得到一个可执行程序mkmini210,目的是通过执行这个mkmini210程序而又led.bin得到210.bin。()
mkv210.image SD启动需要头文件校验
校验和 led.bin计算一个校验和,放在16字节的头文件,然后inand在
分析启动过程可知:210启动后先执行内部irom中的BL0,BL0执行完后会根据OMpn的配置选择一个外部设备来启动,实际使用的由2个:usb启动和sd卡启动。 在usb启动时内部读取到bl1后不做校验,直接从BL1的实质内部0xd0020010开始执行,因此usb的镜像led.bin不需要头信息,因此我们从usb启动时直接将镜像下载到0xd0020010不管头信息。从SD启动时,BL0会首先读取sd卡得到完整的镜像(完整指的是led.bin和16字节的头),然后BL0会自己根据你的实际镜像(指led.bin)来计算一个校验和checksum,然后和你完整镜像的头部中的checksum来比对。如果对应则执行BL1,如果不对应则启动失败(会转入执行2st启动,即SD2启动。如果这里已经是2st启动了,这里校验通不过就死定了)。
copy:
mkv210_image.c的作用:为BL1添加校验头
我们编译链接时只得到了led.bin,这个210.bin的得到和交叉编译工具链是完全无关的。由led.bin得到210.bin的过程是三星的S5PV210所特有的,因此需要我们自己去完成,为此我们写了mkv210_image.c来完成。
1.4.6.4、整个程序工作流分析
整个程序中首先申请一个16KB大小的buffer,然后把所有内容按照各自的位置填充进去,最终把填充好的buffer写入到一个文件(名叫210.bin)就形成了我们想要的镜像。
1.4.7.mkv210_image.c文件详解2
1.4.7.1、代码详解
第1步:检验用户传参是不是3个。
第2步:分配16K Bbuffer并且填充为0.
第3步:·········
1.4.7.2、main函数两个形参的作用
main函数接收2个形参:argc和argv。
argc是用户(通过命令行来)执行这个程序时,实际传递的参数个数。注意这个个数是包含程序执行本身的
argv是一个字符串数组,这个数组中存储的字符串就是一个个的传参。
譬如我们执行程序时使用./mkx210 led.bin 210.bin
则argc = 3
则argv[0] = "./mkx210" argv[1] = led.bin argv[2] =210.bin
1.4.7.3、glibc读写文件接口
linux中要读取一个文件,可以使用fopen打开文件,fread读取文件,读完之后fclose关闭文件。
要写文件用fwrite来写。这些函数是glibc的库函数,在linux中用man 3 可以查找。
如果你本身就知道这些函数的用法,只是记不起来可以man查找;如果你本身根本就不会用这些接口,建议先去baidu。
1.4.7.4、校验和的计算方法
算法:校验和其实就是需要校验的内存区域中,所有内存中的内容按照字节为单位来进行相加,最终相加的和极为校验和。
实现时大家要注意指针的类型为char *
在今天的学习中,有种蒙逼的感觉
- 早上的SD卡下载刷机失败。
- makefile的知识缺陷。
- mkv210_image.c 的源代码中大量C语言的使用。
- glibc函数库在linux下的使用。
- 校验和的原理与s5pv210启动过程关联、关系。