野火I.MX6ULL 从0开始制作SD卡裸板led程序镜像 ---------(Linux踩坑之旅)

前言
2个月前入手了一块二手的IMX6ULL的板子,终于走上Linux系统学习、ARM体系架构学习的道路 学习视频因为穷就只买得起 韦东山老师以前的jz2440的视频 正因为这样走了不少弯路,查度娘 查谷歌 都没有找到讲得很详细,(可能是我粗心 没有找到),决定写篇博客 时刻提醒自己 自己白菜一个,写的有错,欢迎高手指教

一.镜像格式

了解过6ull启动流程的朋友,知道了6ull的启动配备了不同的镜像引导驱动入下图:
野火I.MX6ULL 从0开始制作SD卡裸板led程序镜像 ---------(Linux踩坑之旅)_第1张图片
6ull完全支持SD卡的镜像启动方式,在这里顺便简单说一下 整块板子的启动流程 有装过电脑的朋友,可能知道电脑的BIOSS我们做嵌入式开发的板子也有这个类似的东西叫做 iROM (Boot ROM) ,板子以上电就从iROM中读取第一条程序,板子可以通过管脚选择boot mode 通过 Boot eFUSE参数配置boot引导设备
野火I.MX6ULL 从0开始制作SD卡裸板led程序镜像 ---------(Linux踩坑之旅)_第2张图片
野火I.MX6ULL 从0开始制作SD卡裸板led程序镜像 ---------(Linux踩坑之旅)_第3张图片
然后将镜像文件矫对后就把程序拷贝到内部的SRAM 中运行程序 内部SDRAM的大体划分如下
野火I.MX6ULL 从0开始制作SD卡裸板led程序镜像 ---------(Linux踩坑之旅)_第4张图片
大概了解启动流程后,就可以制作镜像了(后面有时间会专门写一篇博客仔仔细细说一篇)

在学其他非Linux单片机之前都是用各种IDE(集成开发环境)就直接从main函数直接写就行了,但是Linux的开发没有具体的集成开发环境只有一步一步
我自己大概总结了一下分以下步骤
1.汇编文件的编写
2.C文件的编写
3.汇编文件和C文件的编译链接生成可执行文件
4.剥离编译器在代码中的调试信息生成二进制文件
5.根据各个芯片厂商的代码镜像格式给二进制文件添上 校验头
野火I.MX6ULL 从0开始制作SD卡裸板led程序镜像 ---------(Linux踩坑之旅)_第5张图片
具体的制作方法可以查看用户手册 因为厂家直接给了我们制作imx镜像的c程序文件就不必要自己去写程序 做imx镜像了
野火I.MX6ULL 从0开始制作SD卡裸板led程序镜像 ---------(Linux踩坑之旅)_第6张图片
(个人感觉Linux嵌入式板子就是个麻雀,电脑有的基本上它都有,只不过电脑的内存条 是板子的SRAM,DDR等,电的硬盘存储器是板子的flash,eMMC,SD等,那么我们嵌入式板子有了内存条、有了硬盘、有有核心的CPU处理器 现在flash SRAM DDR容量越来越大,逐渐嵌入式的板子可以干很多很多事情了)

二.Linux虚拟机平台下制作SD裸板镜像制作流程

了解了镜像制作的基本流程后直接上正题
1.GCC编译器:
我刚刚开始用的gcc是其他版本的总有问题,我也没有解决,我干脆就换了厂家提供的gcc编译器

arm-linux-gnueabihf-gcc   //gcc version4.9.4(Linaro GCC 4.9-2017.01)

2.编译多文件程序:
.S文件用as汇编器编译 得到.o目标文件
.c文件用gcc编译 得到.o目标文件
得到所有的 .o目标文件后 通过ld链接器 得到最终的elf格式的可执行文件
在通过objcopy 剥离掉 调试信息 得到.bin二进制文件

 led.bin:led
  4     arm-linux-gnueabihf-objcopy -O binary led led.bin
  5 led:start.o led.o
  6     arm-linux-gnueabihf-ld -T imx6ull.lds start.o led.o -o led
  7 start.o:start.S
  8     arm-linux-gnueabihf-as  start.S -o start.o
  9 led.o:led.c
 10      arm-linux-gnueabihf-gcc -c led.c   -o led.o

得到所有目标文件后 进行链接的时候 要把汇编文件生成的text代码段放在整个elf的最前面 imx6ull.lds如下文件内容

1 SECTIONS {
  2     . = 0x80001000; //起始elf文件起始地址
  3
  4     . = ALIGN(4);
  5     .text      :   //代码段
  6     {
  7         start.o
  8       *(.text)  
  9     }
 10
 11     . = ALIGN(4);  
 12     .rodata : { *(.rodata) } //只读数据段
 13
 14     . = ALIGN(4);
 15     .data : { *(.data) }     //数据代码段
 16
 17     . = ALIGN(4);
 18     __bss_start = .;        //未定义代码段
 19     .bss : { *(.bss) *(.COMMON) }
 20     __bss_end = .;
 21 }

我解释一下为啥要有汇编文件,为啥要链接格式
第一个C语言的运行条件之一需要堆栈 在芯片上电的时候为啥 就知道你的堆栈地址 就arm体系架构来说 SP就是堆栈指针寄存器 汇编代码的好处就是没有堆栈呀这些的需要,汇编的本质就是机器代码的抽象 (比如说 CPU读取到代码中的001001 0010001:就把SP寄存器写入对应的值 汇编就是这样简单粗暴)汇编可以 通过一系列寄存器的操作后 为C语言的运行搭建好运行环境
链接为啥要把start汇编文件放在最前面 就是想让CPU先执行汇编后 后面的代码才能正确执行
3.生成后缀为.imx文件:
通过厂家imx制作程序将.bin文件制作成.imx文件

mkimage -n imximage.cfg.cfgtmp -T imximage -e 0x80001000 -d led.bin led.imx

得到.imx文件 打开可以看见入下图
野火I.MX6ULL 从0开始制作SD卡裸板led程序镜像 ---------(Linux踩坑之旅)_第7张图片
生成的.imx文件可以看见 已经生成了 “校验的头部”
然后我就用Windows平台的镜像工具
野火I.MX6ULL 从0开始制作SD卡裸板led程序镜像 ---------(Linux踩坑之旅)_第8张图片
准备烧写,这样永远 试试了30多把,就是不成功!!!!! why?
在商家给我的裸板程序镜像中我发现了原因
野火I.MX6ULL 从0开始制作SD卡裸板led程序镜像 ---------(Linux踩坑之旅)_第9张图片

校验的头 居然 偏移了1k的地址为啥 !! 请看刚刚镜像制作的框图 程序镜像的的头留出了一段空白,这个我在Windows平台下没有找到直接把imx文件生成img文件的方法
4.生成后缀为.img文件:
Linux 下用dd命令将imx文件写入SD卡时 写入到 SD卡0地址后1024的地址
/dev/sdb为SD卡在我电脑上的启动名字(可以用lsblk查看)

sudo dd iflag=dsync oflag=dsync if=led.imx of=/dev/sdb seek=2

三. Windows平台烧写SD的方法

因为我暂时没有找到烧写的方法所有我找了一个Linux生成img文件的方法:
1.新建一个img文件

touch led.img

2.烧写到img里

sudo dd iflag=dsync oflag=dsync if=led.imx of=led.img seek=2

在用.img文件通过Windows平台将img文件烧写到SD中 选择好启动模式 上电启动,程序正常运行!!

你可能感兴趣的:(嵌入式linux)