LV04-02-点灯-03-裸机程序烧写
本文主要烧写裸机程序的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
Windows版本 | windows11 |
Ubuntu版本 | Ubuntu16.04的64位版本 |
VMware® Workstation 16 Pro | 16.2.3 build-19376536 |
终端软件 | MobaXterm(Professional Edition v23.0 Build 5042 (license)) |
Linux开发板 | 正点原子 i.MX6ULL Linux 阿尔法开发板 |
uboot | NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03) |
linux内核 | linux-4.15(NXP官方提供) |
Win32DiskImager | Win32DiskImager v1.0 |
点击查看本文参考资料
分类 | 网址 | 说明 |
官方网站 | https://www.arm.com/ | ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档 |
https://www.nxp.com.cn/ | NXP官方网站 | |
https://www.nxpic.org.cn/ | NXP 官方社区 | |
https://u-boot.readthedocs.io/en/latest/ | u-boot官网 | |
https://www.kernel.org/ | linux内核官网 |
点击查看相关文件下载
分类 | 网址 | 说明 |
NXP | https://github.com/nxp-imx | NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库 |
https://elixir.bootlin.com/linux/latest/source | 在线阅读linux kernel源码 | |
nxp-imx/linux-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga | NXP linux内核仓库tags中的rel_imx_4.1.15_2.1.0_ga | |
nxp-imx/uboot-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga | NXP u-boot仓库tags中的rel_imx_4.1.15_2.1.0_ga | |
I.MX6ULL | i.MX 6ULL Applications Processors for Industrial Products | I.MX6ULL 芯片手册(datasheet,可以在线查看) |
i.MX 6ULL Applications ProcessorReference Manual | I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网) |
一、概述
我们之前学习STM32的时候知道编译完代码以后可以直接通过 MDK 或者 IAR下载到内部的 flash 中。但是 I.MX6U 虽然内部有 96K 的 ROM,但是这 96K 的 ROM 是 NXP 自己用的,不向用户开放。所以相当于说 I.MX6U 是没有内部 flash 的,但是我们的代码得有地方存放啊,为此, I.MX6U 支持从外置的 NOR Flash、 NAND Flash、 SD/EMMC、 SPI NOR Flash和 QSPI Flash 这些存储介质中启动,所以我们可以将代码烧写到这些存储介质中。
在这些存储介质中,除了 SD 卡以外,其他的一般都是焊接到了板子上的,我们没法直接烧写。但是 SD卡是活动的,是可以从板子上插拔的,我们可以将 SD 卡插到电脑上,在电脑上使用软件将 .bin 文件烧写到 SD 卡中,然后再插到板子上就可以了。其他的几种存储介质是我们量产的时候用到的,量产的时候代码就不可能放到 SD 卡里面了,毕竟 SD 是活动的,不牢固,而其他的都是焊接到板子上的,很牢固。
因此,我们在调试裸机和 Uboot 的时候是将代码下载到 SD 中,因为方便嘛,当调试完成以后量产的时候要将裸机或者 u-boot 烧写到 SPI NOR Flash、 EMMC、 NAND 等这些存储介质中的。那么,如何将我们前面编译出来的 led.bin 烧写到 SD 卡中呢?
编译出来的可执行文件是怎么存放到 SD 中的,存放的位置是什么?这个 NXP 是有详细规定的!我们必须按照 NXP 的规定来将代码烧写到 SD 卡中,否则代码是绝对运行不起来的。《i.MX 6ULL Applications Processor Reference Manual》的第 8 章“Chapter 8 System Boot”就是专门讲解 I.MX6U 启动的,在前边我们已经学习过了。正点原子专门编写了一个软件来将编译出来的.bin 文件烧写到 SD 卡中,这个软件名字为“ imxdownload ”。
二、imxdownload说明
1. 工具源码
1.1 imxdownload.c
点击查看 imxdownload.c 源码
1 |
|
1.2 imxdownload.h
这个文件里边的就是DCD信息,不同的芯片可能都是不一样的,需要注意。
点击查看 imxdownload.h 文件
1 |
|
2. 编译工具
上边只是源码,我们想要使用的话,还需要进行编译,我们由于是在ubuntu中使用此工具,所以直接在ubuntu中使用gcc编译即可。
1 | gcc imxdownload.c -o imxdownload -Wall |
然后我们就会得到一个 imxdownload 可执行文件,我们运行这个文件就可以将相应的uboot烧写到sd卡中。
3. 使用方式
我们之前已经生成好了led.bin文件,然后就是在ubuntu下降此文件烧写到sd卡中。我们可以执行以下命令查看一下SD卡在ubuntu中的节点:
1 | sudo fdisk -l |
然后可以看到自己的SD卡的节点:
注意使用的是这个/dev/sdc节点,sdc1是SD卡的1分区,不要用这个。然后我们可以执行以下命令完成烧写:
1 | ./imxdownload <.bin file> <SD Card> |
在这里的话就是:
1 | ./imxdownload led.bin /dev/sdc |
烧写的过程中可能会让输入密码,输入 ubuntu 密码即可完成烧写,烧写过程如下:
烧写的最后一行会显示烧写大小、用时和速度,比如 led.bin 烧写到 SD 卡中的大小是 3.2KB,用时 0.0205983s,烧写速度是 157KB/s。注意这个烧写速度,如果这个烧写速度在几百 KB/s 以下那么就是正常烧写。如果这个烧写速度大于几十 MB/s、甚至几百 MB/s 那么肯定是烧写失败了!
解决方法就是重新插拔 SD 卡,一般出现这种情况,重新插拔 SD 卡基本没啥用,只有重启 ubuntu,至于原因嘛,不详。
三、怎么得到imx文件
我们知道,生成了bin文件后,还需要将这个bin文件变为.imx文件,上边我们知道imxdownload这个工具可以直接将bin文件生成imx文件,然后烧写到sd卡中去,那不使用这个工具呢?其实也是有办法的。办法需要从u-boot中找,后边学习u-boot就会知道,编译u-boot的话,会生成bin文件,也会生成imx文件。如下图:
图中就是之前学习另一款开发板的时候编译u-boot的时候就会有这些文件。
1. DCD数据去哪里找?
前边学习映像文件的时候,有提到过,i.mx6ull的imximage.cfg文件位于u-boot源码的 board/freescale/mx6ullevk/ 目录下这个imximage.cfg文件中就是厂家提供的DCD数据啦:
2. mkimage
这个工具的是u-boot编译完成后,会在tools目录下生成的,它的源码及可执行文件如下:
这是之前学习其他板子的时候编译的,这个工具与开发板无关,是u-boot的工具,所以这里可以直接拿来用。该工具的使用命令如下:
1 | ./mkimage -n ./imximage.cfg -T imximage -e <链接地址> -d <.bin文件> <.imx文件> |
【注意】这里的链接地址要与生成bin文件的时候使用的链接地址一样。
3. 生成.imx文件
我们拷贝上边的 imximage 工具和 board/freescale/mx6ullevk/imximage.cfg 文件到我们的led汇编代码目录下:
可以看到里边有一个load.imx文件,就是上边我们通过正点原子的 imxdownload 工具生成的,我们现在用u-boot中的工具imximage 试一下生成一个imx文件:
1 | ./mkimage -n ./imximage.cfg -T imximage -e 0X87800000 -d led.bin led.imx |
额,然后就直接报错了:
怀疑是文件不对?我就去编译了NXP官方imx6ull-evk板的u-boot的源码目录中又搜了一把:
于是就又发现,编译过的目录生成的有这个imximage.cfg.cfgtmp文件,我没有去搜u-boot的makefile文件中是如何使用这个文件的,我直接用这个文件试了一下就可以了:
1 | ./mkimage -n ./imximage.cfg.cfgtmp -T imximage -e 0X87800000 -d led.bin led.imx |
然后就可以了:
其实数据还是那些,不过还有一些带#号的行出现,没有深究,就直接用就是了。
4. 对比区别
我们通过两种途径生成了imx文件,它们的IVT和DCD一样吗?我们用对比工具对比一下看看:
反正看起来前边的这个数据都是一模一样的,可以直接烧写一下看看能不能跑就知道了。烧写后会发现其实是一样的。那有啥区别?区别就在于,正点原子提供给我们的imxdownload软件把链接地址写死为0x87800000,这意味着什么?这就意味着我们在后面编写链接脚本的时候只能用这个地址作为链接地址,我们的程序都将从这个地址开始存放,想修改怎么办?抱歉,没办法,除非修改imxdownload的源码,但是mkimage这个软件不一样,是在使用软件的时候指定了链接地址,这样我们就可以自定义啦。所以推荐还是用这个软件比较好。
四、烧写img文件到SD卡
上边我们通过正点原子的imxdownload工具直接在ubuntu下完成imx文件的生成和烧写,那我们现在有一个imx文件,怎么办?回到bin文件?肯定不是啦,在ubuntu和windows下都有烧写的办法,这一节就来了解一下如何将imx文件烧写到sd卡中吧。
1. img文件
1.1 1K字节的空文件
为什么要有一个1K字节的空文件?原因就在于这个IVT,如下图:
IVT的偏移的话,在sd卡中,mmc都需要偏移1KB,而我们生成的imx文件,IVT直接从0开始,所以需要制作一个IVT偏移了1K的文件。我们在ubuntu编译好了imx文件后,可以先做一个1K字节的空文件:
1 | dd if=/dev/zero of=1k.bin bs=1024 count=1 |
dd命令 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。上边的命令含义就是以/dev/zero作为输入文件,1k.bin作为输出文件,同时设置读入/输出的块大小为1024个字节(1KB),仅拷贝1个块。这样我们就会生成一个1KB的1k.bin文件啦:
1.2 生成img文件
接下来将imx文件和1k.bin文件合并起来,注意1k.bin文件要在前,这样才能保证生成的img文件的IVT在1K的偏移处:
1 | cat 1k.bin led.imx > led.img |
2. windows下烧写img文件
2.1 Win32DiskImager软件
我们需要借助Win32DiskImager这个软件来吧img文件写入到sd卡中去,我们可以在这里下载这个软件:Win32 Disk Imager download | SourceForge.net,这个软件安装一路默认就好了,打开如下图所示:
2.2 烧写img文件
如上图所示:【选择img文件】→【选中要烧写的sd卡盘符】→【写入】,写入完成则会有以下提示:
然后点击OK,再退出即可。
3. ubuntu下烧写img文件
ubuntu下的话,可以使用dd命令,使用该命令我们甚至可以不需要1k的哪个空文件,直接通过这个命令将imx文件烧写到sd卡挂载节点的1k处:
1 | sudo dd if=led.imx of=/dev/sdc bs=1k seek=1 conv=fsync |
烧写完成会有如下提示:
除了上面的命令,我们还可以使用正点原子提供的哪个烧写工具,那个其实也一样的,只是它是通过c语言的system函数来执行了dd这个shell命令。
五、启动测试
代码已经烧写到了 SD 卡中了,接下来就是将 SD 卡插到开发板的 SD 卡槽中,然后设置拨码开关为 SD 卡启动,拨码开关设置如图 :
设置好以后按一下开发板的复位键,如果代码运行正常的话 LED0 就会被点亮 :