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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "imxdownload.h"

#define SHELLCMD_LEN (200)
#define BIN_OFFSET (3072)

/* 此宏指明是否打印u-boot.imx的IVT DCD表信息,不同的开发板其IVT和DCD
* 表的数据是不同的,因此需要获取所使用的开发板的IVT和DCD表信息,最
* 简单的方法就是读取开发板配套资料里面的u-boot.imx的前1KB数据,理论上
* 应该读取3KB的数据,但是表信息远远没有3K这么多,因此读1KB即可
*/
#define PRINT_TAB 0
/*
* 介绍: 此软件是针对NXP的IMX6U系列芯片的,软件用来烧写bin文件到SD卡里面,
* 本软件会自动添加IVT、DCD等信息到原始的bin文件里面,主要用于裸机和uboot的烧写。
* 使用方法: 1、编译好原始的二进制bin文件,如,u-boot.bin等,并将编译好的.bin文件和本
* 软件放置到同一个目录下!!!!
* 2、执行命令sudo ./imxdownload <soucre_bin> <sd_device>
* 如烧写u-boot.bin到/dev/sdd中即可使用如下所示命令:
* sudo ./imxdownload u-boot.bin /dev/sdd
*/

/*
* 输出一些信息
*/
void message_print(void)
{
printf("I.MX6ULL bin download software\r\n");
printf("Edit by:zuozhongkai\r\n");
printf("Date:2019/6/10\r\n");
printf("Version:V1.1\r\n");
printf("log:V1.0 initial version,just support 512MB DDR3\r\n");
printf(" V1.1 and support 256MB DDR3\r\n");
}

int main(int argc, char *argv[])
{
FILE *fp;
unsigned char *buf;
unsigned char *cmdbuf;
int nbytes, filelen;
int i = 0, j = 0;
int ddrsize = 0; /* 0为512MB,1为256MB,2为128MB...... */

message_print();

if((argc != 3) && (argc != 4)){
printf("Error Usage! Reference Below:\r\n");
printf("sudo ./%s <-512m or -256m> <source_bin> <sd_device>\r\n", argv[0]);
return -1;
}

/* 查找参数,获取DDR容量 */
for(i = 0; i < argc; i++)
{
char *param = argv[i];
if(param[0] != '-')
continue;
if(strcmp(param, "-256m") == 0) /* 256MB */
ddrsize = 1;
else if(strcmp(param, "-512m") == 0) /* 512MB */
ddrsize = 0;
}
if(argc == 3) /* 三个参数,也就是不输入DDR容量的话默认为512MB */
ddrsize = 0;

/* 打开bin文件 */
fp = fopen(argv[1], "rb"); /* 以二进制只读方式打开bin文件 */
if(fp == NULL){
printf("Can't Open file %s\r\n", argv[1]);
return -1;
}

/* 获取bin文件长度 */
fseek(fp, 0L, SEEK_END);
filelen = ftell(fp);
fseek(fp, 0L, SEEK_SET);
printf("file %s size = %dBytes\r\n", argv[1], filelen);

/* 读取bin文件到缓冲区buf中 */
buf = malloc(filelen + BIN_OFFSET);
if(buf == NULL){
printf("Mem Malloc Failed!\r\n");
fclose(fp);
return -1;
}
memset(buf, 0, filelen + BIN_OFFSET); /* 清零 */
/* 读取bin源码文件 */
fread(buf + BIN_OFFSET, 1, filelen, fp);

/* 关闭文件 */
fclose(fp);

#if PRINT_TAB
printf("IVT DCD Table:\r\n");
for(i = 0; i < 1024/32; i++){
for(j = 0; j < 8; j++)
{
printf("0X%08X,",*(int *)(buf + BIN_OFFSET + (((i * 8) + j) * 4)));
}
printf("\r\n");
}
free(buf);
return 0;
#endif

/* 添加IVT DCD等表信息到bin文件里面 */
if(ddrsize == 0) { /* 512MB */
printf("Board DDR SIZE: 512MB\r\n");
memcpy(buf, imx6_512mb_ivtdcd_table, sizeof(imx6_512mb_ivtdcd_table));
}
else if (ddrsize == 1) { /* 256MB */
printf("Board DDR SIZE: 256MB\r\n");
memcpy(buf, imx6_256mb_ivtdcd_table, sizeof(imx6_256mb_ivtdcd_table));
}

/* 现在我们已经在buf中构建好了可以用于下载的bin文件,将buf中的数据保存到
* 到一个文件中,文件命名为load.imx
*/
printf("Delete Old load.imx\r\n");
system("rm -rf load.imx"); /* 先删除旧的load.imx文件 */

printf("Create New load.imx\r\n");
system("touch load.imx"); /* 创建新的load.imx文件 */
fp = fopen("load.imx", "wb"); /* 打开laod.imx */
if(fp == NULL){
printf("Cant't Open load.imx!!!\r\n");
free(buf);
return -1;
}
nbytes = fwrite(buf, 1, filelen + BIN_OFFSET, fp);
if(nbytes != (filelen + BIN_OFFSET)){
printf("File Write Error!\r\n");
free(buf);
fclose(fp);
return -1;
}
free(buf);
fclose(fp);

/* 构建烧写的shell命令 */
cmdbuf = malloc(SHELLCMD_LEN);
sprintf(cmdbuf, "sudo dd iflag=dsync oflag=dsync if=load.imx of=%s bs=512 seek=2",argv[2]);
printf("Download load.imx to %s ......\r\n", argv[2]);

/* 执行上面的shell命令 */
system(cmdbuf);
free(cmdbuf);
return 0;
}

1.2 imxdownload.h

这个文件里边的就是DCD信息,不同的芯片可能都是不一样的,需要注意。

点击查看 imxdownload.h 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#ifndef _IMXDOWNLOAD_H
#define _IMXDOWNLOAD_H
/* IMX6U IVT DCD表信息 暂时定义为1K Bytes,此表是读取的u-boot.imx前1K Bytes
* imx6_ivedcd_table[9]是指明代码长度的,本应该根据实际的代码长度来修改
* 这里为了方便,就直接定义为2M Bytes,即
*/

const int imx6_512mb_ivtdcd_table[256] = {
0X402000D1,0X87800000,0X00000000,0X877FF42C,0X877FF420,0X877FF400,0X00000000,0X00000000,
0X877FF000,0X00200000,0X00000000,0X40E801D2,0X04E401CC,0X68400C02,0XFFFFFFFF,0X6C400C02,
0XFFFFFFFF,0X70400C02,0XFFFFFFFF,0X74400C02,0XFFFFFFFF,0X78400C02,0XFFFFFFFF,0X7C400C02,
0XFFFFFFFF,0X80400C02,0XFFFFFFFF,0XB4040E02,0X00000C00,0XAC040E02,0X00000000,0X7C020E02,
0X30000000,0X50020E02,0X30000000,0X4C020E02,0X30000000,0X90040E02,0X30000000,0X88020E02,
0X30000C00,0X70020E02,0X00000000,0X60020E02,0X30000000,0X64020E02,0X30000000,0XA0040E02,
0X30000000,0X94040E02,0X00000200,0X80020E02,0X30000000,0X84020E02,0X30000000,0XB0040E02,
0X00000200,0X98040E02,0X30000000,0XA4040E02,0X30000000,0X44020E02,0X30000000,0X48020E02,
0X30000000,0X1C001B02,0X00800000,0X00081B02,0X030039A1,0X0C081B02,0X0B000300,0X3C081B02,
0X44014801,0X48081B02,0X302C4040,0X50081B02,0X343E4040,0X1C081B02,0X33333333,0X20081B02,
0X33333333,0X2C081B02,0X333333F3,0X30081B02,0X333333F3,0XC0081B02,0X09409400,0XB8081B02,
0X00080000,0X04001B02,0X2D000200,0X08001B02,0X3030331B,0X0C001B02,0XF3526B67,0X10001B02,
0X630B6DB6,0X14001B02,0XDB00FF01,0X18001B02,0X40172000,0X1C001B02,0X00800000,0X2C001B02,
0XD2260000,0X30001B02,0X23106B00,0X40001B02,0X4F000000,0X00001B02,0X00001884,0X90081B02,
0X00004000,0X1C001B02,0X32800002,0X1C001B02,0X33800000,0X1C001B02,0X31800400,0X1C001B02,
0X30802015,0X1C001B02,0X40800004,0X20001B02,0X00080000,0X18081B02,0X27020000,0X04001B02,
0X2D550200,0X04041B02,0X06100100,0X1C001B02,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000
};

const int imx6_256mb_ivtdcd_table[256] = {
0X402000D1,0X87800000,0X00000000,0X877FF42C,0X877FF420,0X877FF400,0X00000000,0X00000000,
0X877FF000,0X00076000,0X00000000,0X40E801D2,0X04E401CC,0X68400C02,0XFFFFFFFF,0X6C400C02,
0XFFFFFFFF,0X70400C02,0XFFFFFFFF,0X74400C02,0XFFFFFFFF,0X78400C02,0XFFFFFFFF,0X7C400C02,
0XFFFFFFFF,0X80400C02,0XFFFFFFFF,0XB4040E02,0X00000C00,0XAC040E02,0X00000000,0X7C020E02,
0X30000000,0X50020E02,0X30000000,0X4C020E02,0X30000000,0X90040E02,0X30000000,0X88020E02,
0X30000C00,0X70020E02,0X00000000,0X60020E02,0X30000000,0X64020E02,0X30000000,0XA0040E02,
0X30000000,0X94040E02,0X00000200,0X80020E02,0X30000000,0X84020E02,0X30000000,0XB0040E02,
0X00000200,0X98040E02,0X30000000,0XA4040E02,0X30000000,0X44020E02,0X30000000,0X48020E02,
0X30000000,0X1C001B02,0X00800000,0X00081B02,0X030039A1,0X0C081B02,0X04000000,0X3C081B02,
0X3C013C01,0X48081B02,0X38324040,0X50081B02,0X28304040,0X1C081B02,0X33333333,0X20081B02,
0X33333333,0X2C081B02,0X333333F3,0X30081B02,0X333333F3,0XC0081B02,0X09409400,0XB8081B02,
0X00080000,0X04001B02,0X2D000200,0X08001B02,0X3030331B,0X0C001B02,0XF352433F,0X10001B02,
0X630B6DB6,0X14001B02,0XDB00FF01,0X18001B02,0X40172000,0X1C001B02,0X00800000,0X2C001B02,
0XD2260000,0X30001B02,0X23104300,0X40001B02,0X47000000,0X00001B02,0X00001883,0X90081B02,
0X00004000,0X1C001B02,0X32800002,0X1C001B02,0X33800000,0X1C001B02,0X31800400,0X1C001B02,
0X30802015,0X1C001B02,0X40800004,0X20001B02,0X00080000,0X18081B02,0X27020000,0X04001B02,
0X2D550200,0X04041B02,0X06100100,0X1C001B02,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
};

#endif

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卡的节点:

image-20230716203141888

注意使用的是这个/dev/sdc节点,sdc1是SD卡的1分区,不要用这个。然后我们可以执行以下命令完成烧写:

1
./imxdownload <.bin file> <SD Card>

在这里的话就是:

1
./imxdownload led.bin /dev/sdc

烧写的过程中可能会让输入密码,输入 ubuntu 密码即可完成烧写,烧写过程如下:

image-20230716203419165

烧写的最后一行会显示烧写大小、用时和速度,比如 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文件。如下图:

image-20230716204345754

图中就是之前学习另一款开发板的时候编译u-boot的时候就会有这些文件。

1. DCD数据去哪里找?

前边学习映像文件的时候,有提到过,i.mx6ull的imximage.cfg文件位于u-boot源码的 board/freescale/mx6ullevk/ 目录下这个imximage.cfg文件中就是厂家提供的DCD数据啦:

image-20230716204156660

2. mkimage

这个工具的是u-boot编译完成后,会在tools目录下生成的,它的源码及可执行文件如下:

image-20230716204601272

这是之前学习其他板子的时候编译的,这个工具与开发板无关,是u-boot的工具,所以这里可以直接拿来用。该工具的使用命令如下:

1
./mkimage -n ./imximage.cfg -T imximage -e <链接地址> -d <.bin文件> <.imx文件>

【注意】这里的链接地址要与生成bin文件的时候使用的链接地址一样。

3. 生成.imx文件

我们拷贝上边的 imximage 工具和 board/freescale/mx6ullevk/imximage.cfg 文件到我们的led汇编代码目录下:

image-20230716205212792

可以看到里边有一个load.imx文件,就是上边我们通过正点原子的 imxdownload 工具生成的,我们现在用u-boot中的工具imximage 试一下生成一个imx文件:

1
./mkimage -n ./imximage.cfg -T imximage -e 0X87800000 -d led.bin led.imx

额,然后就直接报错了:

image-20230716210655037

怀疑是文件不对?我就去编译了NXP官方imx6ull-evk板的u-boot的源码目录中又搜了一把:

image-20230716211406512

于是就又发现,编译过的目录生成的有这个imximage.cfg.cfgtmp文件,我没有去搜u-boot的makefile文件中是如何使用这个文件的,我直接用这个文件试了一下就可以了:

1
./mkimage -n ./imximage.cfg.cfgtmp -T imximage -e 0X87800000 -d led.bin led.imx

然后就可以了:

image-20230716211657956

其实数据还是那些,不过还有一些带#号的行出现,没有深究,就直接用就是了。

4. 对比区别

我们通过两种途径生成了imx文件,它们的IVT和DCD一样吗?我们用对比工具对比一下看看:

image-20230716212636453

反正看起来前边的这个数据都是一模一样的,可以直接烧写一下看看能不能跑就知道了。烧写后会发现其实是一样的。那有啥区别?区别就在于,正点原子提供给我们的imxdownload软件把链接地址写死为0x87800000,这意味着什么?这就意味着我们在后面编写链接脚本的时候只能用这个地址作为链接地址,我们的程序都将从这个地址开始存放,想修改怎么办?抱歉,没办法,除非修改imxdownload的源码,但是mkimage这个软件不一样,是在使用软件的时候指定了链接地址,这样我们就可以自定义啦。所以推荐还是用这个软件比较好。

四、烧写img文件到SD卡

上边我们通过正点原子的imxdownload工具直接在ubuntu下完成imx文件的生成和烧写,那我们现在有一个imx文件,怎么办?回到bin文件?肯定不是啦,在ubuntu和windows下都有烧写的办法,这一节就来了解一下如何将imx文件烧写到sd卡中吧。

1. img文件

1.1 1K字节的空文件

为什么要有一个1K字节的空文件?原因就在于这个IVT,如下图:

image-20230716103844353

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文件啦:

image-20230716214922380

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,这个软件安装一路默认就好了,打开如下图所示:

image-20230716215247142

2.2 烧写img文件

image-20230716215423457

如上图所示:【选择img文件】→【选中要烧写的sd卡盘符】→【写入】,写入完成则会有以下提示:

image-20230716215513838

然后点击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

烧写完成会有如下提示:

image-20230716215956077

除了上面的命令,我们还可以使用正点原子提供的哪个烧写工具,那个其实也一样的,只是它是通过c语言的system函数来执行了dd这个shell命令。

五、启动测试

代码已经烧写到了 SD 卡中了,接下来就是将 SD 卡插到开发板的 SD 卡槽中,然后设置拨码开关为 SD 卡启动,拨码开关设置如图 :

image-20240117190003663

设置好以后按一下开发板的复位键,如果代码运行正常的话 LED0 就会被点亮 :

image-20240117190017669