Skip to content

LV010-启动方式简介

一开始,我们在体验系统的时候就需要使用拨码开关,令系统从 eMMC 启动或者从 SD 卡启动,那么,imx6ull 芯片上电的时候,它怎么知道从哪启动的?

一、手册内容解读

首先我们先看参考手册:《i.MX 6ULL Applications Processor Reference Manual 》的 Chapter 8 System Boot ,这一部分就是专门讲解 I.MX6ULL 启动相关内容的章节。

1. boot ROM 概述

I.MX6ULL 芯片内部有一个 boot ROM,上电后 boot ROM 上的程序就会运行。它会根据 BOOT_MODE [1:0] 的值,以及 eFUSE 或 GPIO 的值决定后续的启动流程。

说明: eFUSE 即熔丝,只能烧写一次,一般正式发布产品时烧写最终值;平时调试时通过 GPIO 来设置开发板的启动方式。

boot ROM 上的程序功能强大,可以从 USB 口或串口下载程序并把它烧写到 Flash 等设备上,也可以从 SD 卡或 EMMC、 Flash 等设备上读出程序、运行程序。

那么考虑一个问题:boot ROM 是从 USB 口下载、运行程序,还是从 SD 卡等设备上读出、运行程序,谁决定? 我们接着往下看。

2. boot ROM 是下载还是读出?

2.1 由什么决定下载还是读出?

还是上面的问题:boot ROM 是从 USB 口下载、运行程序,还是从 SD 卡等设备上读出、运行程序,谁决定?

答案是由 BOOT_MODE [1:0] 的值来决定的,这个 boot ROM 是下载还是读出,其实就是 imx6ull 的启动方式,这两个寄存器的值来自于 2 个引脚 BOOT_MODE1、 BOOT_MODE0。这 2 个引脚在上电时是输入引脚,芯片启动后采集这 2 个引脚的值,存入 BOOT_MODE 寄存器。以后这 2 个引脚就可以用于其他功能,不会影响到 BOOT_MODE 寄存器。 BOOT_MODE [1:0] 的值确定了 4 种启动模式:

image-20230716074402242

在正点原子的开发板中,这两个引脚的原理图如下:

image-20230716074826207

其中 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” 就是低电平。

2.2 四种模式

2.2.1 00 模式

也就是从 FUSE 启动,在我们的开发过程中很少用到。简单介绍一下。

在这种模式下, GPIO 的值被忽略。boot ROM 会根据 eFUSE 的值来选择启动设备、设置启动设备。但是,对于刚出厂的芯片 eFUSE 值可能是错乱的、不适合我们的设备的,那这怎么办?eFUSE 中有一个值 BT_FUSE_SEL,它的出厂值是 0,表示 eFUSE 未被烧写。 boot ROM 程序发现 BT_FUSE_SEL 为 0 时,它会通过 USB 或串口来下载程序;发现 BT_FUSE_SEL 为 1 时,才会根据 eFUSE 的值选择启动设备,读出、运行该设备上的程序。

2.2.2 01 模式

就是 串行下载模式。 此模式下 boot ROM 程序可以通过 USB 或串口下载、运行程序。这种模式可以将代码下载到板子上的外置存储设备中,我们可以使用 OTG1 这个 USB 口向开发板上的 SD/EMMC、 NAND 等存储设备下载代码。我们需要将 BOOT_MODE1 拨到“OFF”,将 BOOT_MODE0 拨到“ON”。开发板出厂时,一般就是通过这个模式下载、烧写出厂程序的。

2.2.3 10 模式

称之为内部模式(内部 BOOT 模式),简单地说就是从 SD 卡、 EMMC 等设备启动程序。当 BOOT_MODE1 为 1, BOOT_MODE0 为 0 的时候此模式使能,在此模式下,芯片会执行内部的 boot ROM 代码,这段 boot ROM 代码会进行硬件初始化(一部分外设),然后从 boot 设备(就是存放代码的设备、比如 SD/EMMC、 NAND)中将代码拷贝出来复制到指定的 RAM 中,一般是 DDR。

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

image-20230909104803582

在图中 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、 L2 Cache 和 MMU。

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

2.2.4 11 模式

11 模式一般是保留的。

2.3 支持从哪些设备启动?

可以看手册的《Chapter 8 System Boot → 8.1 Overview 》

image-20241031064903128

当 BOOT_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) QuadSPI(QSPI) Flash。

(5)接到 USDHC 接口上的 SD/MMC/eSD/SDXC/eMMC 等设备。

(6)SPI 接口的 NOR flash 和 EEPROM。

总的来说就是支持这一些:NOR flash、NAND flash、OneNAND flash、SD/MMC、Serial (SPI) NOR flash and EEPROM、QuadSPI (QSPI) flash 。

这些启动设备如何选择呢? I.MX6U 提供了 eFUSE 和 GPIO 配置两种。

3. 如何选择和设置启动设备?

3.1 怎么区分 eFUSE 和 GPIO 的情况?

00 模式下是通过 eFUSE 的值选择启动设备,我们不关心。10 模式下既可以通过 eFUSE 的值也可以通过 GPIO 的值来选择启动设备(谁说的?一开始没找到,后看翻了手册还真有说明):

image-20230716081521843

但是到底通过谁来决定? 上图其实已经给了答案:eFUSE 中有一个值 BT_FUSE_SEL,它的初始值为 0,表示 eFUSE 未被烧写。在 10 模式下,当 BT_FUSE_SEL 为 0 时就会通过 GPIO 来选择启动设备;当 BT_FUSE_SEL 为 1 时就会通过 eFUSE 来选择启动设备。 BT_FUSE_SEL 默认也就是 0,在开发阶段,我们就可以使用 GPIO 来选择设备啦。

3.2 选择启动设备

通过 eFUSE 或 GPIO 不仅能选择启动设备,还可以设置启动设备。为什么还需要设置?比如 Nand Flash 参数各有不同, 有些的页大小是 2048,有些是 4096。这些参数不同, boot ROM 程序读 Nand Flash 的方法就不同,我们必须把这些参数告诉 boot ROM:通过 eFUSE 或 GPIO 来标明这些参数。

首先看看要设置哪些 eFUSE 或 GPIO 来选择不同的启动设备。我们既可以使用 eFUSE 也可以使用 GPIO 来选择启动设备,GPIO 可以覆盖 eFUSE 的值。

哪些 GPIO 覆盖哪些 eFUSE?这可以查看《i.MX 6ULL Applications Processor Reference Manual 》中 Chapter 8: System Boot 里的 GPIO boot overrides 。选择启动设备后,还需要标明一些参数。比如选择 EMMC 启动时, EMMC 接在哪一个接口, eSDHC1 还是 eSDHC2?它的速度如何?比如选择 TF 卡启动时, TF 卡接在哪一个接口, eSDHC1 还是 eSDHC2?它的速度如何?假设使用 EMMC 启动,或是 TF 卡启动,怎么设置 eFUSE 或 GPIO?这些信息可以查询《i.MX 6ULL Applications Processor Reference Manual 》的 Chapter 5:Fusemap。

正如启动模式由 BOOT_MODE [1:0] 来选择一样,启动设备是通过 BOOT_CFG1 [7:0]、 BOOT_CFG2 [7:0] 和 BOOT_CFG4 [7:0] 这 24 个配置 IO,这 24 个配置 IO 刚好对应着 LCD 的 24 根数据线 LCD_DATA0~LCDDATA23,当启动完成以后这 24 个 IO 就可以作为 LCD 的数据线使用。这 24 根线和 BOOT_MODE1、 BOOT_MODE0 共同组成了 I.MX6U 的启动选择引脚,下图列出了一小部分:

image-20230716082623499

图中所示的是 BOOT_CFG [7:4],这四个引脚的的值是在串行模式下决定从 NOR/OneNAND、QSPI、SD/eSD/SDXC、MMC/eMMC 等设备启动,这几个引脚对应的就是 LCD1_DATA [7:4] 这几个 GPIO。这几个书要是选择启动设备,剩下的引脚主要是用于设置启动设备。

3.3 设置启动设备?

选择启动设备后,还需要标明一些参数。比如选择 EMMC 启动时,EMMC 接在哪一个接口,eSDHC1 还是 eSDHC2?它的速度如何?选择 TF 卡启动时,TF 卡接在哪一个接口,eSDHC1 还是 eSDHC2?它的速度如何?假设使用 EMMC 启动,或是 TF 卡启动,怎么设置 eFUSE 或 GPIO?这些信息可以查询 i.MX6ULL 参考手册《Chapter 5: Fusemap》:

image-20230716090343139

前边我们知道 BOOT_MODE [1:0] 设置启动模式(下边的 0b 表示位):

  • 当 BOOT_MODE 设置为 0b00 时,通过 eFUSE 选择启动设备,通过 eFUSE 获得设备的参数。

  • 当 BOOT_MODE 设置为 0b10 时,通过 eFUSE 或 GPIO 来选择启动设备,获得设备的参数;使用 eFUSE 还是 GPIO 由 eFUSE 中的 BT_FUSE_SEL 决定,它默认是 0,表示使用 GPIO。

以 BOOT_MODE 为 0b10 为例,我们看一下要设置为 SD 卡、 TF 卡启动的话要怎么搞:

选择启动的设备为 SD/TF 卡

(1)设置 eFUSE 的 BOOT_CFG1 [7:5] 为 0b010 ;

(2)查看 i.MX6ULL 参考手册的《8.3.2 GPIO boot overrides 》确定 BOOT_CFG1 [7:5] 对应的 GPIO 为 LCD1_DATA07~05,把这 3 个引脚设置为 0b010。

根据 SD 卡、 TF 卡的性能,可以设置 eFUSE 或 GPIO 来表示它能否提供更高的速度:

设置 SD/TF 卡参数

(1)设置 eFUSE 的 BOOT_CFG1 [4:0]

(2)查看 i.MX6ULL 参考手册的《8.3.2 GPIO boot overrides 》确定 BOOT_CFG1 [4:0] 对应的 GPIO 为 LCD1_DATA04~00,设置这些引脚。

(3)IMX6ULL 有两个 SD 卡、 TF 卡接口,使用哪一个接口?设置 eFUSE 的 BOOT_CFG2 [4:3] 可以确定使用 eSDHC1 或 eSDHC2。

image-20260114122904045

(4)查看 i.MX6U 参考手册的《8.3.2 GPIO boot overrides 》确定 BOOT_CFG2 [4:3] 对应的 GPIO 为 LCD1_DATA12~11,设置这些引脚

二、ALPHA 板中的启动方式

前边我们知道选择启动设备的时候要调整这 24 个 IO 的高低电平,这得多复杂啊?其实不然,虽然有 24 个 IO,但是实际需要调整的只有那几个 IO,其它的 IO 全部下拉接地即可,也就是设置为 0。打开 I.MX6U-ALPHA 开发板的核心板原理图,这 24 个 IO 的默认设置如图所示:

image-20230716083416304

大部分的 IO 都接地了,只有几个 IO 接高,尤其是 BOOT_CFG4 [7:0] 这 8 个 IO 都 10K 电阻下拉接地,所以我们压根就不需要去关注 BOOT_CFG4 [7:0]。我们需要重点关注的就只剩下了 BOOT_CFG2 [7:0] 和 BOOT_CFG1 [7:0] 这 16 个 IO。

image-20230716091307001

BOOT_CFG1 [7:0] 和 BOOT_CFG2 [7:0] 这 16 个 IO 还能不能在减少呢?我们打开 I.MX6U-ALPHA 开发板的底板原理图,底板上启动设备选择拨码开关原理图如图所示:

image-20230716091358040

除 了 BOOT_MODE1 和 BOOT_MODE0 必须引出来,LCD_DATA3~LCDDATA7、 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 的配置含义如表:

image-20230716091809953

BOOT IO 含义, I.MX6U-ALPHA 开发板从 SD 卡、 EMMC、 NAND 启动的时候拨码开关各个位设置方式如下表

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

参考资料:

i.MX6UL 的启动流程——野火