ARM裸机篇(二)

您所在的位置:网站首页 嵌入式启动过程图 ARM裸机篇(二)

ARM裸机篇(二)

2024-07-09 03:46:25| 来源: 网络整理| 查看: 265

linux系列目录: linux基础篇(一)——GCC和Makefile编译过程 linux基础篇(二)——静态和动态链接 ARM裸机篇(一)——i.MX6ULL介绍 ARM裸机篇(二)——i.MX6ULL启动过程 ARM裸机篇(三)——i.MX6ULL第一个裸机程序 ARM裸机篇(四)——重定位和地址无关码 ARM裸机篇(五)——异常和中断 linux系统移植篇(一)—— linux系统组成 linux系统移植篇(二)—— Uboot使用介绍 linux系统移植篇(三)—— Linux 内核使用介绍 linux系统移植篇(四)—— 根文件系统使用介绍 linux驱动开发篇(一)—— Linux 内核模块介绍 linux驱动开发篇(二)—— 字符设备驱动框架 linux驱动开发篇(三)—— 总线设备驱动模型 linux驱动开发篇(四)—— platform平台设备驱动

文章目录 一、 i.MX6ULL启动流程二、i.MX6ULL镜像格式三、镜像实例四、制作镜像五、烧写镜像

一、 i.MX6ULL启动流程

I.MX6U 支持多种启动方式以及启动设备,比如可以从 SD/EMMC、 NAND Flash、 QSPI Flash等启动。 i.MX6UL完整的启动流程如下图所示,完成启动任务的代码位于0x0000 0000 地址处的Boot ROM。 在这里插入图片描述 启动流程过程大致可分为六步。①检查CPU的ID ,②检查复 位状态,③获取启动方式,④加载程序映像,⑤校验映像,⑥跳转到映像去执行。

i.MX6ULL有四个启动模式,如下表,具体使用哪种启动模式通过内部寄存器 BOOT_MODE 中的值来选择,如图: 在这里插入图片描述 当 BOOT_MODE 设置为内部 BOOT 模式以后,所谓“内部”是相对于“Serial Download”来说的,“内部”可以认为是 i.MX6ULL 支持的启动存储设备,例如 emmc、 nandflash、 SD card、norFlash 等等。具体从那种“内部”设备启动,由 BOOT_CFG1[7:4] 决定,如下表所示。表内部启动方式选择: 在这里插入图片描述

二、i.MX6ULL镜像格式

知道启动方式后 Boot ROM 代码并不能立即加载启动映像,因为我们的代码保存在芯片外部存储设备,从这些存储设备读数据之前首先要进行初始化。在 Boot ROM 程序根据保存在芯片中的默认配置信息配置这些存储器接口。

I.MX6ULL 的最终可烧写文件组成如下: ①、 Image vector table,简称 IVT, IVT 里面包含了一系列的地址信息,这些地址信息在ROM 中按照固定的地址存放着。 在这里插入图片描述

②、 Boot data,启动数据,包含了镜像要拷贝到哪个地址,拷贝的大小是多少等。 在这里插入图片描述

③、 Device configuration data,简称 DCD,设备配置信息,重点是 DDR3 的初始化配置。 在这里插入图片描述

④、用户代码可执行文件,比如 led.bin。

最终烧写到 I.MX6U 中的程序其组成为: IVT+Boot data+DCD+.bin。 在这里插入图片描述

这4部分内容合并成为一个映像文件,烧写在EMMC、SD卡或TF卡等启动设备的某个固定地址,boot ROM程序去这个固定地址读出映像文件。启动设备不同,固定地址不同,如下图: 在这里插入图片描述

三、镜像实例

制作映像文件的起点是:我们编写的程序。制作过程中各项值的计算方法如下图所示。 在这里插入图片描述 按照上述的配置,板子上电后Boot Rom会根据上述的配置初始化时钟和DDR3,然后会将映像文件从启动设备(TF卡、eMMC)自动拷贝到DDR3内存上。Boot Rom应该将映像文件拷贝到内存的哪个位置,上述的配置文件已经规定好了,拷贝到DDR3中的位置和大小由Boot data数据决定,用户.bin文件的起始地址由地址entry决定,需要在链接脚本中手动配置。假设.bin文件的起始地址为0X87800000。复制结束后,CPU会从这个地址读取第一条指令开始执行程序。

四、制作镜像

假设我们已经有了一个led.S的裸机程序,然后经过编译链接到0X87800000这个地址,使用objcopy工具转换成bin文件:

arm-none-eabi-gcc -c led.S -o led.o arm-none-eabi-ld -Ttext 0X87800000 led.o -o led.elf arm-none-eabi-objcopy -O binary -S -g led.elf led.bin 确定入口地址entry: 我们的程序运行时要放在内存中哪一个位置,这是我们决定的,由于我们把程序链接到了0X87800000,所以此地址就是程序的入口地址。确定映像文件在内存中的地址start: boot ROM程序启动时,会把“Initial Load Region”读出来,“Initial load Region”里含有IVT、Boot data、DCD。boot ROM根据DCD初始化设备后,再把整个映像文件读到内存。 在启动设备上,“Initial Load Region”之后紧跟着我们的程序,反过来说就是我们程序的前面,放着“Initial Load Region”。“Initial Load Region”的大小为load_size,那么在内存中“Initial Load Region”的位置start = entry – load_size=0X87800000 - 0x1000 = 0X877FF000。确定IVT在内存中的地址self: self = start + ivt_offset = 0X877FF000 + 0x400 = 0X877FF400确定Boot data在内存中的地址boot_data: IVT结构的大小是32个字节,IVT之后就是Boot data,而IVT中的boot_data值表示Boot data在内存中的位置,计算如下: boot_data = self + 32 =0X877FF400+32=0X877FF420确定DCD在内存中的地址dcd: Boot data结构的大小是12字节,Boot data之后就是DCD,而IVT中的dcd值表示DCD在内存中的位置,计算如下: dcd = boot_data + 12 = 0X877FF420 + 0x0C = 0X877FF42C写入DCD的数据 DCD是用初始化硬件的,特别是初始化DDR。而DDR的初始化非常的复杂、专业,我们一般是使用硬件厂家提供的代码。写入用户程序

经过上述7个步骤,映像文件就构建出来了,可以把它烧入启动设备。

把上述步骤,可以写成如下代码,自动为我们完成映像的制作: imxdownload.c:

#include "stdio.h" #include "stdlib.h" #include "string.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 * 如烧写u-boot.bin到/dev/sdd中即可使用如下所示命令: * sudo ./imxdownload u-boot.bin /dev/sdd */ /* 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, }; /* * 输出一些信息 */ 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 \r\n", argv[0]); return -1; } /* 查找参数,获取DDR容量 */ for(i = 0; i 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 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; }

编译:

gcc imxdownload.c -o imxdownload

使用方法:

sudo ./imxdownload

推荐在usr/local/bin 文件夹下建立软链接,后续可以直接使用imxdownload命令:

sudo ln -s ~/imx6ull/tools/imxdownload/imxdownload /usr/local/bin/imxdownload

测试: 在这里插入图片描述

五、烧写镜像

将USB读卡器插入电脑后,默认连接到主机,将鼠标放到USB图标上(虚拟机右下角状态栏), 单击鼠标右键如下所示,选择将读卡器连接到虚拟机上。

在将读卡器连接到虚拟机之后,使用lsblk查看,增加出来的设备就是我们内存卡的标识名。 我们当然不需要手工去计算,一个mkimage命令就搞定了。 使用imxdownload命令进行烧写:imxdownload led.bin /dev/sdb 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭