正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6.5

2024-04-29 11:36

本文主要是介绍正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6.5,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 前言:

本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。

引用:

正点原子IMX6U仓库 (GuangzhouXingyi) - Gitee.com

《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.5.2.pdf》第 8.1 章

《正点原子资料_A盘/02开发板原理图/IMX6ULL_MINI_V2.2(Mini底板原理图).pdf》

  • 资料盘 开发板资料链接: https://pan.baidu.com/s/1j5Jzbdx9i-g0cWIi3wf2XA 提取码:ag1u


正文:

本文是 “正点原子[第二期]Linux之ARM(MX6U)裸机篇--第6.5讲” 的读书笔记。第6.5讲 I.MX6U 芯片的启动方式。

0. I.MX6U 启动方式详解

I.MX6U 支持多种启动方式以及启动设备,比如可以从 SD/MMC,NAND Flash,QSPIFlash 等启动。用户可以根据实际情况,选择合适的启动设备。不同的启动方式,其启动方式和启动要求也不一样,比如上一张的从 SD 卡启动就需要在 bin 文件前面添加一个数据头,其它的启动设备也是需要这个数据头的。本章我们就来学习一下 I.MX6U 的启动方式,以及不同设备启动的要求。

1. 启动方式的选择

BOOT 的处理过程是发生在 I.MX6U 芯片上电以后,芯片会根据 BOOT_MODE[1:0] 的设备来选择 BOOT 方式。BOOT_MODE[1:0] 的值是可以改变的,有两种方式,一种是改写 eFUSE (熔丝),一种是修改相应的 GPIO 高低电平。第一种修改 eFUSE 的方式只能修改一次,后面就不能再修改了,所以我们不使用。我们用的是通过修改 BOOT_MODE[1:0] GPIO 对应的高低电平来选择启动方式,所有的开发板都使用的这种方式,I.MX6U 有一个 BOOT_MODE1 引脚和 BOOT_MODE0 引脚,这两个引脚对应 BOOT_MODE[1:0] 。I.MX6U -ALPHA/Mini 开发板的这两个引脚的电路原理图如下图所示:

其中 BOOT_MODE1 和 BOOT_MODE0 在芯片内部是有 100KΩ 下拉电阻的,所以默认是0。 BOOT_MODE1 和 BOOT_MODE0 这两个引脚我们也接到了底板上的拨码开关上,这样我们就可以通过拨码开关来控制  BOOT_MODE1 和 BOOT_MODE0 的高低电平。以  BOOT_MODE1 为例,当我们把 BOOT_CFG 的第一个开关拨到 “ON” 位置时,就相当于 BOOT_MODE1 引脚通过 R88 这个 10K 电阻接到了 3.3V 电源,芯片内部的 BOOT_MODE1 又是 100K 下拉电阻接地,因此 BOOT_MODE1 的电压就是 100(10+100)*3.3v=3V,这个就是高电平,因此 BOOT_CFG 的8个开关拨到“ON” 就是高电平,拨到“OFF”就是低电平。

而 I.MX6U 有四个 BOOT 模式,这四个 BOOT 模式由 BOOT_MODE[1:0] 来控制,也就是 BOOT_MODE1 和 BOOT_MODE0 这两个IO,BOOT 模式的配置如下表所示:

BOOT_MODE[1:0]BOOT类型
00从 FUSE 启动
01串行下载
10内部BOOT模式
11保留

在 表 9.1.1 中,我们只用到第二种和第三种BOOT方式。

1.1 串行下载

当 BOOT_MODE1 为0, BOOT_MODE0=1的时候使能此模式,串行下载的意思就是可以通过USB或UART将代码下载到板子上的外置存储设置中,我们可以使用 OTG1 这个 USB 口向开发板上的 SD/EMMC ,NAND 等存储设备下载代码。我们需要将 BOOT_MODE1 拨到 “OFF”,将 BOOT_MODE0 拨到“ON”。这个下载需要用到NXP提供的一个软件,一般用来最终量产的时候将代码烧写到外置的存储设备总的,我们后面讲解如何使用。

1.2 内部BOOT方式

当 BOOT_MODE1 为1, BOOT_MODE0=0的时候使能此模式,在此模式下,芯片会执行内部 bootROM 代码,这段 bootROM 代码会进行硬件初始化(一部分外设),然后从 boot 设备(也就是存放代码的设备,比如 SD/EMMC,NAND)中将代码拷贝复制到RAM中,一般是放在DDR中。

2. BOOT ROM 初始化内容

当我们设置 BOOT 模式为 “内部BOOT模式”以后,I.MX6U 的把内部 boot ROM 代码就是执行,这个 boot ROM 代码会做什么处理呢?首先肯定是初始化时钟,boot ROM 设置的系统是中国如下图所示:

在上图中 BT_FREQ 模式为0,可以看到,boot ROM 会将 I.MX6U 的内核时钟设置为 396MHz,也就是主频为 396MHz。System PLL=528Mhz,USB PLL=480MHz,AHB=132MHz,IPG=66MHz。关于I.MX6U的系统时钟,我们后面会详细讲解。

内部 boot ROM 为了加快执行速度回打开 MMU 和 Cache:

  • 下载镜像的时候 L1 ICache 会打开,
  • 验证镜像的时候 L1 DCache,L2 Cache 和 MMU 都会打开。
  • 一旦镜像验证完成,boot ROM 就会关闭 L1 DCache,L2Cache 和 MMU 

中断向量偏移会被设置到 boot ROM 的起始位置,当 boot ROM 启动了用户代码以后就可以重新设置中断向量偏移了。一般是重新设置到我们用户代码开始的地方,关于中断的内容后面会详细讲解。

3. 启动设备

当 BOO_MODE 设置为内部BOOT模式以后,可以从一下设备中启动:

  1. 接到 EIM 接口的 CS0 上的 16 位 NOR Flash。
  2. 接到 EIM 接口的 CS0 上的 OneNAND Flash。
  3. 接到 GPMI 接口上的 MLC/SLC NAND Flash,NAND Flash 页大小支持 2KByte, 4KByte 和 8Kbyte,8位宽。
  4. Quard SPI Flash
  5. 接到 USDHC 接口上的 SD/MMC/eSD/SDXC/eMMC等设备。
  6. SPI接口的 EEPROM

这些设备启动如何选择呢? I.MX6U 同样提供了 eFUSE 和 GPIO 配置两种,eFUSE 就不讲解了。我们重点看如何通过 GPIO 来选择启动设备,因为所有的 I.MX6U 开发板都是通过 GPIO 来配置启动设备的。正如启动模式由 BOOT_MODE[1:0]来选择一样,启动设备是通过 BOOT_CFG1[7:0] ,BOOT_CFG2[7:0] 和 BOOT_CFG4[7:0] 这 24 个配置IO,这24个配置IO刚好对应着 LCD 的24根数据线 LCD_DATA0 ~ LCD_DATA23,当启动完成以后这个24个IO就可以额作为LCD的数据线使用。这24个数据线和 BOOT_MODE1, BOOT_MODE0 共同组成了 I.MX6U 的启动选择引脚,如图 9.3.1 所示:

通过 图 9.3.1 中的 26 个启动IO即可实现 I.MX6U 从不同设备启动,BOOT_MODE1 和 BOOT_MODE0 已经讲述过了。看到这24个 IO 是不是头大?调整这24个IO的高低电平得多复杂啊?起始不然,虽然有24个IO,但是实际需要调整的只有那几个IO,其它的IO全部下拉接地即可,也就是设置为0.打开 I.MX6U-ALPHA/Mini的开发板核心板电路原理图,这24个IO的默认配置如下图所示:

可以从"正点原子 I.MX6U ALPHA"开发板原理图中看出,"正点原子 I.MX6U ALPHA"开发板的 LCD_DATA0~LCD_DATA23 大部分 IO 都接地了,只有几个 IO 拉高,尤其是 BOOT_CFG4[7:0] 这8个IO都有 10 K 电阻下拉接地,所以我们压根就不需要去关心 BOOT_CFG4[7:0]。我们需要中断关注的只剩下了 BOOT_CFG2[7:0] 和 BOOT_CFG1[7:0] 这16个IO。这16个配置IO的含义在原理图的左侧已经贴出来了,如下图所示。

图 9.3.3 看着是不是也很头大,BOOT_CFG1[7:0]和BOOT_CFG2[7:0]这16个IO还能不嗯呢再减少哪?可以,打开 I.MX6U ALPHA/Mini 开发板的底板原理图,底板上设备选择拨码开关原理图如下:

在图 9.3.4 中,除了 BOOT_MODE1 和 BOOT_MODE0 必须印出来,LCD_DATA3~LC_DATA7,LCD_DATA11 这 6个IO也被印出来,可以通过拨码开关来设置其对应的高低电平,拨码开关到 “ON” 就是1,拨码开关到 “OFF” 就是0.齐总 LCD_DATA11 就是 BOOT_CFG2[3],LCD_DATA3~LCD_DATA7 就是 BOOT_CFG1[3]~BOOT_CFG1[7],这6个IO的配置的含义如下表:

BOOT_CFG引脚对应LCD引脚含义
BOOT_CFG2[3]LCD_DATA11为0时SDHC1上的SD/EMMC启动,为1时从SDH2上的SD/EMMC启动。
BOOT_CFG1[3]LCD_DATA3当从SD/EMMC启动的时候设置启动速度,当从NAND启动的时候设置ANND数量。
BOOT_CFG1[4]LCD_DATA4

BOOT_CFG1[7:4]: (高位在前,低位在后)
0000 NOR/OneNAND(EIM)启动

0001 QSPI启动

0011 SPI启动

010x SD/eSD/SDXC启动

011x MMC/eMMC启动

1xxx NAND Flash启动

BOOT_CFG1[5]LCD_DATA5
BOOT_CFG1[6]LCD_DATA6
BOOT_CFG1[7]LCD_DATA7

根据表 9.3.1 中 BOOT IO 含义,I.MX6U-ALPHA/Mini 开发板从SD卡,EMMC,NAND 启动的时候拨码开关各个位置配置方式如下表所示

12345678启动设备
01xxxxxx串行下载,可以通过USB烧写镜像文件
10000010SD卡启动
10100110EMMC启动
10001001NAND FLAHS启动

我们再“第八章 汇编LED实验”中,最终的可执行问价 led.bin 烧写到了 SD 卡里面,然后从SD卡启动,其拨码开关就是根据表 9.3.1 来设置的,通过上面的讲解酒味道为什么拨码开关要这么设置了。

4. 镜像烧写

注意!本小节会分析 bin 文件添加的头部信息,但是在笔者写本教程的时候关于I.MX 系列的SOC头部信息的资料很少,基本智能参考NXP的官方资料,而官方资料有些地方讲解的又不是很详细。所以本节有些部分是笔者根据NXP的官方 u-boot.imx 文件的头部信息反推出来的,因此难免有错误的地方,还望大家谅解!如有发现错误之处,欢迎大家在 www.openedv.com 论坛
上留言。

前面我们设置好 BOOT 以后就能从指定的设备启动了,但是你的设备里面得有代码啊,在第八章我们使用 imxdownload 这个软件将 led.bin 烧写到 SD 卡中。imxdownload 会在 led.bin 前面添加一些头信息,重新生成一个叫做 load.imx 的文件,最终烧写的是 load.imx。那么肯能就有人问:imxdownload 是如何将 led.bin 打包成 load.imx的。

学习STM32的时候我们可以直接将编译生成的.bin文件烧写到STM32内部的Flash里面,但是 I.MX6U 不能直接烧写编译生成的 .bin文件,我们需要再.bin文件前面添加一些头信息构成满足 I.MX6U 需求的最终可烧写文件,I.MX6U的最终可烧写文件注册如下:

  1. Image vector rable,简称 IVT,IVT 里面包含了一系列地址信息,这些地址信息在ROM里按照固定的地址存放着。
  2. Boot data,启动数据,包含了镜像要拷贝到哪个地址,拷贝的大小是多少等等。
  3. Device configuration data,简称 DCD ,设别配置信息,重点是 DDR3 的初始化配置。
  4. 用户代码可执行文件,比如 led.bin 

可以看出最终烧写到 I.MX6U 中的程序其组成为 IVT+Boot data + DCD + .bin 。所以第8章中的 imxdownload 所生成的 load.imx 就是在 led.bin 前面加上 IVT + Boot data + DCD 。内部 boot ROM 会将 load.imx 拷贝到DDR中,用户代码前面又有 3KByte的 IVT+Boot Data + DCD数据,下面会讲一下为什么是 3KByte,因此 load.imx 在DDR中的起始地址就是 0x8780_0000 - 3072 = 0x877F_F400。

4.1 IVT 和 Boot Data 数据

load.imx 最前面就是 IVT 和 Boot Data ,IVT 包含了镜像程序的入口点,指向 DCD指针和一些用作其他用途的指针。内部 boot ROM 要求 IVT 应该放到指定的位置,不同的启动设备位置不同,而 IVT 在整个 load.imx 的最前面,起始就相当于要求 load.imx 在烧写的时候应该烧写到存储设备的指定为止去。整个位置都是相对于存储初设备的起始地址的偏移,如图 9.4.1 所示:

以 SD/EMMC 为例,IVT偏移为 1KByte,IVT+Boot Data+DCD总大小为4KByte - 1KByte = 3KByte。假设 SD/EMMC 每个扇区为 512 字节,那么 load.imx 应该从第三个山城区开始烧写,前两个扇区要流出来。load.imx 从第3KBbyte开始才是真正的 .bin 文件。那么 IVT 里究竟存放着什么东西呢?IVT里存放的内容如下表 9.4.1.2 所示

从 图 9.4.1.2 可以看到,第一个存放的是 head (头),header 的给是如 图 9.4.1.3 所示:

图9.4.3 中,Tag位1字节长度,固定为 0xD1,Length是两个字节,保存着IVT 长度,位大端格式,也就是高字节保存在低内存中。最有的Version是一个字节,为 0x40 或者 0x41。

Boot Data 的数据格式如图 9.4.1.3 所示

实际情况是不是这样的呢?我们用 winhex 打开 load.imx 一看便知,winhex 可以直接查看一个文件的二进制格式数据。用winhex打开 load.imx 如下图所示

图 9.1.4.1 是我们截取的 load.imx 的一部分内容,从地址 0x0000_0000 ~ 0x0000_025F,共608字节的数据。气门将钱44个字节按照4个字节一组组的组合在一起就是,0x402000D1, 0x8780000, 0x00000000, 0x877FF42C,0x877FF420,0x00000000,0x0000000,0x877FF000,0x00200000,0x00000000。这44个字节的内容就是 IVT和Boot Data的数据,按照图 9.4.1.2 和图 9.4.1.4 所示的 IVT 和 Boot Data 所示的格式对应起来如表 9.4.1.1 所示:

4.2 DCD 数据

复位以后,I.MX6U 片内所有寄存器就会复位为默认值,但是这些默认值往往不是我们想要的值,而且有些外设在我们必须在使用之前初始化它。为此 I.MX6U 提出了一个 DCD (device Config Data) 的概念,和 IVT , Boot Data 一样,DCD也是添加到 load.imx 里面的,紧跟在 IVT 和 Boot Data 后面,IVT里面也指定了DCD的位置。DCD起始就是 I.MX6U 寄存器地址和对应配置的集合信息,boot ROM 会使用这些寄存器地址和配置集合来初始化相应的寄存器,比如开启某些外设时钟,初始化DDR等等。DCD去不不能超过 1768 Byte,DCD区域的结构如 9.4.2.1 所示

DCD 的 header 和 IVT 的 header 类似,结构如图 9.4.2.2 所示
中 Tag 是单字节,固定为 0XD2, Length 为两个字节,表示 DCD 区域的大小,包含 header,同样是大端模式, Version 是单字节,固定为 0X40 或者 0X41。

图 9.4.2.1 中的 CMD 就是要初始化的寄存器地址和相应的寄存器值, 结构如图 9.4.2.3 所示:

图 9.4.2.3 中 Tag 为一个字节,固定为 0XCC。 Length 是两个字节,包含写入的命令数据长度,包含 header,同样是大端模式。 Parameter 为一个字节,这个字节的每个位含义如图 9.4.2.4 所示

图 9.4.2.4 中的 bytes 表示是目标位置宽度,单位为 byte,可以选择 1、 2、和 4 字节。 flags 是命令控制标志位。

图 9.4.2.3 中的 Address 和 Vlalue/Mask 就是要初始化的寄存器地址和相应的寄存器值,注意采用的是大端模式! DCD 结构就分析到这里,在分析 IVT 的时候我们就已经说过了, DCD 数据是从图 9.4.1.4 的 0X2C 地址开始的。根据我们分析的 DCD 结构可以得到 load.imx 的 DCD 数据如表 9.4.2.1 所示:

从 表 9.4.2.1 中可以看出,DCD 里面初始化配置主要包括三个方面

  1. 设置CCGR0~CCGR6这个7个外设时钟寄存器,默认打开所有外设时钟
  2. 配置DDR3所用的所有IO
  3. 设置MMDC控制器,初始化DDR3

I.MX6U的启动过程我们就讲解到这里,本章我们详细的讲解了 I.MX6U 的启动模式,启动设备类型,和镜像烧写过程。总结一下,我们编译出来的 .bin 文件不能拿直接烧写到SD卡中,需要再.bin文件前面加上 IVT, Boot DATA和DCD这三个数据块。这三个数据块是有指定格式的,播我们必须按照格式填写,然后将其放到.bin文件前面,最终和策划给你的才是我们可以直接烧写到SD卡中的文件。

这篇关于正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6.5的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/945980

相关文章

nandflash裸机驱动程序的分析

nandflash在嵌入式设备中广泛的应用,学些nandflash的重要性不言而喻,这里分析一段实例代码,不管是编码规范还是程序的结构都是很有价值的。下边是K9F1208U0M的实例代码。 首先看nand.h文件:   #ifndef __NAND_Flash__#define __NAND_Flash__extern void InitNandCfg(void);

【SQL学习进阶】从入门到高级应用(九)

文章目录 子查询什么是子查询where后面使用子查询from后面使用子查询select后面使用子查询exists、not existsin和exists区别 union&union alllimit 🌈你好呀!我是 山顶风景独好 💕欢迎来到我的博客,很高兴能够在这里和您见面! 💕希望您在这里可以感受到一份轻松愉快的氛围! 💕这里不仅可以获得有趣的内容和知识,也可以畅所欲

three.js官方案例(animation / keyframes)webgl_animation_keyframes.html学习

目录 ​编辑 1  PMREMenerator 1.1 构造函数 1.2  fromScene方法 2 AnimationMixer 3 animal1.html全部 4  animal1.js全部 1  PMREMenerator         此类生成预过滤的 Mipmapped 辐射环境贴图 (PMREM) 来自 cubeMap 环境纹理。这允许不同的级别

Keras深度学习框架基础第四讲:层接口(layers API)“层权重约束”

1、层权重约束概述 1.1 层权重约束的定义 Keras层权重约束的定义主要涉及到在训练神经网络模型时,对层的权重参数施加一定的限制或约束,以提高模型的泛化能力和稳定性。以下是关于Keras层权重约束的详细定义: 约束的目的: 防止过拟合:通过限制权重的大小或范围,可以减少模型对训练数据的过度依赖,从而提高模型在未见数据上的性能。 提高模型稳定性:约束可以确保权重参数在合理的范围内变化

LabVIEW与Arm控制器之间的通讯

LabVIEW是一个强大的图形化编程环境,广泛应用于自动化控制、数据采集和测试测量等领域。而Arm控制器则是嵌入式系统中常用的处理器架构,广泛用于各种控制和计算任务。将LabVIEW与Arm控制器进行通讯控制,可以结合二者的优势,实现高效的数据处理和控制系统。本文将详细介绍LabVIEW与Arm控制器之间通讯控制的实现方法,包括硬件配置、通讯协议、软件配置及实例演示。 硬件配置 选择合适的A

Linux 36.3 + JetPack v6.0@jetson-inference之视频操作

Linux 36.3 + JetPack v6.0@jetson-inference之视频操作 1. 源由2. 输入输出源2.1 输入2.2 输出 3. 示例3.1 MIPI CSI 摄像头3.2 V4L2 摄像头3.3 WebRTC3.4 RTP3.5 RTSP3.6 Video 文件3.7 Image 文件 4. 代码分析4.1 Python4.2 C++ 5. 参考资料 1.

AI学习指南机器学习篇-多元线性回归

AI学习指南机器学习篇-多元线性回归 在机器学习领域,多元线性回归是一种用于建立自变量和因变量之间关系的模型。在这篇博客中,我们将讨论多元线性回归模型的引入以及它对多个自变量对因变量的影响。我们还将讨论多元线性回归与简单线性回归的区别和应用场景。 引入多元线性回归模型 多元线性回归是用于研究多个自变量与因变量之间关系的一种统计学方法。它的数学表示形式如下: Y = β 0 + β 1 X

Java基础学习: 代理模式(Proxy Pattern)

文章目录 一、简介1、介绍2、代理模式在Java中的应用 二、实现方式1、静态代理2、动态代理 三、动态代理1、JDK2、Cglib3、总结 参考 一、简介 1、介绍 代理模式 2、代理模式在Java中的应用 统一异常处理。Mybatis使用了代理。Spring aop实现代理。日志框架。 二、实现方式 1、静态代理 在Java中,静态代理是一种代理模式,它涉及为另一

Linux上实现ssh免密通讯

Linux上实现ssh免密通讯 1.SSH互信原理2.SSH所需的RPM包3.两台机器实现互信4.常见问题及处理 1.SSH互信原理 SSH(Secure Shell)是一种安全的传输协议,它能让Linux系统中的服务器和客户端之间进行安全可靠的通讯。 SSH使用加密的传输方式,以保证客户端和服务器之间的通讯安全。默认加密技术:rsa,加密位:2048位,将用户数据和控制指令加密

Linux(Centos)之安装Nginx及注意事项 阅读目录 1.Nginx的简单说明 2.准备工作 3.安装SSL功能需要openssl库以及gzip模块需要的zlib库 4.安装 rewri

阅读目录 1.Nginx的简单说明2.准备工作3.安装SSL功能需要openssl库以及gzip模块需要的zlib库4.安装 rewrite模块需要pcre库5.安装 Nginx服务6.监测Nginx是否安装成功7.将Nginx设置为开机自动启动8.使用server命令启动nginx服务 回到顶部 1.Nginx的简单说明   a.  Nginx是一个高性能的H