【IMX6ULL学习笔记】六、U-BOOT环境变量与Linux启动

发布者:VelvetWhisper最新更新时间:2025-03-05 来源: cnblogs关键字:U-BOOT  环境变量  Linux启动 手机看文章 扫描二维码
随时随地手机看文章

一、环境变量 bootcmd

bootcmd 和 bootagrs 是采用类似 shell 脚本语言编写的,里面很多的变量引用,这些变量都是环境变量,很多是 NXP 定义的。文件mx6ull_alientek_emmc.h 中的宏 CONFIG_EXTRA_ENV_SETTINGS 保存着这些环境变量的默认值,内容如下:


#if defined(CONFIG_SYS_BOOT_NAND)

#define CONFIG_EXTRA_ENV_SETTINGS

    CONFIG_MFG_ENV_SETTINGS

    'panel=TFT43AB'

    'fdt_addr=0x83000000'

    'fdt_high=0xffffffff'

......

        'bootz ${loadaddr} - ${fdt_addr}'


#else

#define CONFIG_EXTRA_ENV_SETTINGS

    CONFIG_MFG_ENV_SETTINGS

    'script=boot.scr'

    'image=zImage'

    'console=ttymxc0'

    'fdt_high=0xffffffff'

    'initrd_high=0xffffffff'

    'fdt_file=undefined'

......

    'findfdt='

        'if test $fdt_file = undefined; then '

         'if test $board_name = EVK && test $board_rev = 9X9; then '

          'setenv fdt_file imx6ull-9x9-evk.dtb; fi; '

    'if test $board_name = EVK && test $board_rev = 14X14; then '

                'setenv fdt_file imx6ull-14x14-evk.dtb; fi; '

            'if test $fdt_file = undefined; then '

            'echo WARNING: Could not determine dtb to use; fi; '

            'fi;'

宏 CONFIG_EXTRA_ENV_SETTINGS 是个条件编译语句,使用 NAND 和 EMMC 的时候宏 CONFIG_EXTRA_ENV_SETTINGS 的值是不同的。用户可以根据需求自定义修改这些默认值,如前面移植 LCD 时修改默认屏幕为'panel=KODO_TFT4384'。


bootcmd 的默认值就是 CONFIG_BOOTCOMMAND,bootargs 的默认值就是 CONFIG_BOOTARGS。


在 mx6ull_alientek_emmc.h 文件中通过设置宏 CONFIG_BOOTCOMMAND 来设置 bootcmd 的默认值,NXP 官方设置的 CONFIG_BOOTCOMMAND 值如下:


#define CONFIG_BOOTCOMMAND

    'run findfdt;'

    'mmc dev ${mmcdev};'

    'mmc dev ${mmcdev}; if mmc rescan; then '

        'if run loadbootscript; then '

            'run bootscript; '

        'else '

            'if run loadimage; then '

                'run mmcboot; '

            'else run netboot; '

            'fi; '

        'fi; '

    'else run netboot; fi'

使用了类似 shell 脚本语言的方式来编写。

第 2 行:run findfdt;使用的是 uboot 的 run 命令来运行 findfdt,findfdt 是 NXP 自行添加的环境变量。findfdt 是用来查找开发板对应的设备树文件(.dtb)。IMX6ULL EVK 的设备树文件为 imx6ull-14x14-evk.dtb,findfdt 内容如下:


'findfdt='

'if test $fdt_file = undefined; then '

'if test $board_name = EVK && test $board_rev = 9X9; then '

        'setenv fdt_file imx6ull-9x9-evk.dtb; fi; '

    'if test $board_name = EVK && test $board_rev = 14X14; then '

        'setenv fdt_file imx6ull-14x14-evk.dtb; fi; '

    'if test $fdt_file = undefined; then '

        'echo WARNING: Could not determine dtb to use; fi; '

'fi;'

findfdt 里面用到的变量有 fdt_file,board_name,board_rev,这三个变量内容如下:


fdt_file=undefined,board_name=EVK,board_rev=14X14

findfdt 做的事情就是判断,fdt_file 是否为 undefined,如果 fdt_file 为 undefined 的话那就要根据板子信息得出所需的.dtb 文件名。

此时 fdt_file 为 undefined,所以根据 board_name 和 board_rev 来判断实际所需的.dtb 文件,如果 board_name 为 EVK 并且 board_rev=9x9 的话 fdt_file 就为 imx6ull-9x9-evk.dtb。如果 board_name 为 EVK 并且 board_rev=14x14 的话 fdt_file 就设置为 imx6ull-14x14-evk.dtb。因此 IMX6ULL EVK 板子的设备树文件就是 imx6ull-14x14-evk.dtb,因此 run findfdt 的结果就是设置 fdt_file 为 imx6ull-14x14-evk.dtb。

第 3 行:mmc dev

m

m

c

d

e

v

m

m

c

m

m

c

d

e

v

1

m

m

c

d

e

v

1

E

M

M

C

4

m

m

c

d

e

v

{mmcdev}切换到 EMMC 上,然后使用命令 mmc rescan 扫描看有没有 SD 卡或者 EMMC 存在,如果没有的话就直接跳到 216 行,执行 run netboot,netboot 也是一个自定义的环境变量,这个变量是从网络启动 Linux 的。如果 mmc 设备存在的话就从 mmc 设备启动。

第 5 行:运行 loadbootscript 环境变量,此环境变量内容如下:


loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};

其中 mmcdev=1,mmcpart=1,loadaddr=0x80800000,script= boot.scr,因此展开以后就是:


loadbootscript=fatload mmc 1:1 0x80800000 boot.scr;

loadbootscript 就是从 mmc1 的分区 1 中读取文件 boot.src 到 DRAM 的 0X80800000 处。但是 mmc1 的分区 1 中没有 boot.src 这个文件,可以使用命令“ls mmc 1:1”查看一下 mmc1 分区 1 中的所有文件,看看有没有 boot.src 这个文件。

第 6 行:如果加载 boot.src 文件成功的话就运行 bootscript 环境变量,bootscript 的内容如下:


bootscript=echo Running bootscript from mmc ...;

source

因为 boot.src 文件不存在,所以 bootscript 也就不会运行。

第 8 行:如果 loadbootscript 没有找到 boot.src 的话就运行环境变量 loadimage,环境变量 loadimage 内容如下:


loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}

其中 mmcdev=1,mmcpart=1,loadaddr=0x80800000,image = zImage,展开以后就是:


loadimage=fatload mmc 1:1 0x80800000 zImage

可以看出 loadimage 就是从 mmc1 的分区中读取 zImage 到内存的 0X80800000 处,而 mmc1 的分区 1 中存在 zImage。

第 9 行:加载 linux 镜像文件 zImage 成功以后就运行环境变量 mmcboot,否则的话运行 netboot 环境变量。mmcboot 环境变量如下:


'mmcboot=echo Booting from mmc ...; '

    'run mmcargs; '

    'if test ${boot_fdt} = yes || test ${boot_fdt} = try; then '

        'if run loadfdt; then '

            'bootz ${loadaddr} - ${fdt_addr}; '

        'else '

            'if test ${boot_fdt} = try; then '

                'bootz; '

            'else '

                'echo WARN: Cannot load the DT; '

            'fi; '

        'fi; '

    'else '

        'bootz; '

    'fi;'

第 1 行:输出信息“Booting from mmc ...”。

第 2 行:运行环境变量 mmcargs,mmcargs 用来设置 bootargs,后面分析 bootargs 的时候再学习。

第 3 行:判断boot_fdt是否为 yes 或者 try,根据 uboot 输出的环境变量信息可知 boot_fdt=try。因此会执行第 4 行的语句。

第 4 行:运行环境变量 loadfdt,环境变量 loadfdt 定义如下:


loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}

展开以后就是:


loadfdt=fatload mmc 1:1 0x83000000 imx6ull-14x14-evk.dtb

因此 loadfdt 的作用就是从 mmc1 的分区 1 中读取 imx6ull-14x14-evk.dtb 文件并放到 0x83000000 处。

第 5 行:如果读取.dtb 文件成功的话那就调用命令 bootz 启动 linux,调用方法如下:


bootz ${loadaddr} - ${fdt_addr};

展开就是:


bootz 0x80800000 - 0x83000000 (注意‘-’前后要有空格)

至此 Linux 内核启动,如此复杂的设置就是为了从 EMMC 中读取 zImage 镜像文件和设备树文件。经过分析,浓缩出来的仅仅是 4 行精华:


mmc dev 1                       //切换到 EMMC

fatload mmc 1:1 0x80800000 zImage //读取 zImage 到 0x80800000 处

fatload mmc 1:1 0x83000000 imx6ull-14x14-evk.dtb //读取设备树到 0x83000000 处

bootz 0x80800000 - 0x83000000     //启动 Linux

二、环境变量 bootargs

bootargs 保存着 uboot 传递给 Linux 内核的参数,在上一小节讲解 bootcmd 的时候说过,bootargs 环境变量是由 mmcargs 设置的,mmcargs 环境变量如下:


mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}

其中 console=ttymxc0,baudrate=115200,mmcroot=/dev/mmcblk1p2 rootwait rw,因此将 mmcargs 展开以后就是:


mmcargs=setenv bootargs console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw

可以看出环境变量 mmcargs 就是设置 bootargs 的值为“console= ttymxc0, 115200 root=/dev/mmcblk1p2 rootwait rw”,bootargs 就是设置了很多的参数的值,这些参数 Linux 内核会使用到,常用的参数有:


1、console 参数

console 用来设置 linux 终端(或者叫控制台),也就是通过什么设备来和 Linux 进行交互,是串口还是 LCD 屏幕?如果是串口的话应该是串口几等等。一般设置串口作为 Linux 终端,这样我们就可以在电脑上通过 SecureCRT 来和 linux 交互了。这里设置 console 为 ttymxc0,因为 linux 启动以后 I.MX6ULL 的串口 1 在 linux 下的设备文件就是/dev/ttymxc0,在 Linux 下,一切皆文件。

ttymxc0 后有个“,115200”,是设置串口波特率,console=ttymxc0,115200 综合起来就是设置 ttymxc0(也就是串口 1)作为 Linux 的终端,并且串口波特率设置为 115200。


2、root 参数

root 用来设置根文件系统的位置,root=/dev/mmcblk1p2 用于指明根文件系统存放在 mmcblk1 设备的分区 2 中。EMMC 版本的核心板启动 linux 以后会存在/dev/mmcblk0、/dev/mmcblk1、/dev/mmcblk0p1、/dev/mmcblk0p2、/dev/mmcblk1p1 和/dev/mmcblk1p2 这样的文件,其中/dev/mmcblkx(x=0~n)表示 mmc 设备,而/dev/mmcblkxpy(x=0n,y=1n)表示 mmc 设备 x 的分区 y。在 I.MX6U-ALPHA 开发板中/dev/mmcblk1 表示 EMMC,而/dev/mmcblk1p2 表示

EMMC 的分区 2。

root 后面有“rootwait rw”,rootwait 表示等待 mmc 设备初始化完成以后再挂载,否则的话 mmc 设备还没初始化完成就挂载根文件系统会出错的。rw 表示根文件系统是可以读写的,不加 rw 的话可能无法在根文件系统中进行写操作,只能进行读操作。


3、rootfstype 参数

此选项一般配置 root 一起使用,rootfstype 用于指定根文件系统类型,如果根文件系统为 ext 格式的话此选项无所谓。如果根文件系统是 yaffs、jffs 或 ubifs 的话就需要设置此选项,指定根文件系统的类型。


4、mem 参数

mem=xxM 指定内存的大小,不是必须的

5、ramdisk_size 参数(一般不用)

ramdisk 即虚拟内存盘,是通过软件将部分内存模拟为硬盘来使用的一种技术。


ramdisk=xx      //不推荐

ramdisk_size=xx //推荐

上面这两个都可以告诉 ramdisk 驱动,创建的 ramdisk 的 size,默认情况下是4m(s390默认8M),可以查看 Documentation/ramdisk.txt 找到相关的描述,不过 ramdisk=xx 在新版的内核都已经没有提了,不推荐使用。


6、initrd、noinitrd 参数

当没有使用 ramdisk 启动系统的时候,需要使用 noinitrd 这个参数,但是如果使用了的话,就需要指定 initrd=r_addr,size,r_addr 表示 initrd 在内存中的位置,size 表示 initrd 的大小。


7、 init 参数

init 指定内核启动后进入系统中运行的第一个脚本,一般 init=/linuxrc, 或者 init=/etc/preinit,preinit 的内容一般是创建 console null 设备节点、运行 init 程序、挂载一些文件系统等操作。


注:很多初学者以为 init=/linuxrc 是固定写法,其实不然,/linuxrc 指的是/目录下面的 linuxrc 脚本,一般是一个链接罢了。

此参数一般不需要设置,因为内核源码中有一定的启动项,内核如何启动 init 进程在内核的 init/main.c 中 static init noinline init_post(void)。


若出现 No init found Try passing init= 这种错误的时候可能原因是内核找不到文件系统或者无法挂载文件系统,不用考虑是init参数设置的错误。


Eg:kernelpanic-nosyncing :no init found.Tying init= option to know 此错误的原因是因为 root=/dev/mtdblock4 但是 nand 中没有烧写文件系统,而不是因为 init 参数设置不对。


8、mtdparts 参数

mtdparts=fc000000.nor_flash:1920k(linux),128k(fdt),20M(ramdisk),4M(jffs2),38272k(user),256k(env),384k(uboot)

要想这个参数起作用,内核中的 mtd 驱动必须要支持,即内核配置时需要选上:


Device Drivers ---> 

Memory Technology Device (MTD) support---> 

Command line partition table parsing

mtdparts 的格式如下:


mtdparts=[;mtdparts 可以由一个或多个 mtddef 组成。每个mtddef定义如下:


:= :[,]

mtddef 可以由 mtd-id 和一个或多个 partdef 组成,每个 partdef 定义如下:


:= [@offset][][ro]

参数含义如下:


:= unique id used in mapping driver/device

:= standard linux memsize OR '-' to denote all remaining space

:= (NAME)

因此在使用的时候,需要按照下面的格式来设置:


mtdparts=mtd-id:@(),@()

这里需要注意的地方如下:

(1) mtd-id 必须跟当前平台 flash 的 mtd-id 一致,不然整个 mtdparts 会失效。

(2)size 在设置的时候,可以为实际的 size(xxM,xxK,xx),也可以为‘-’,表示剩余的所有空间,相关信息可以查看 drivers/mtd/cmdlinepart.c 中注释找到相关描述。


mtdparts 参数格式及当前平台的 flash 的 mtd-id 如何查找?

先看看 linux-4.14.63/Documentation 里面怎么说的:


~/opt/linux-4.14.63/Documentation$ grep mtdparts . -rn                   

./admin-guide/kernel-parameters.txt:2408:       mtdparts=       [MTD]

[1] [2]
关键字:U-BOOT  环境变量  Linux启动 引用地址:【IMX6ULL学习笔记】六、U-BOOT环境变量与Linux启动

上一篇:【IMX6ULL学习笔记】七、Linux 顶层Makefile
下一篇:【IMX6ULL学习笔记】五、U-BOOT移植与解析

推荐阅读最新更新时间:2026-03-16 22:28

IMX6ULL学习笔记】六、U-BOOT环境变量Linux启动
一、环境变量 bootcmd bootcmd 和 bootagrs 是采用类似 shell 脚本语言编写的,里面很多的变量引用,这些变量都是环境变量,很多是 NXP 定义的。文件mx6ull_alientek_emmc.h 中的宏 CONFIG_EXTRA_ENV_SETTINGS 保存着这些环境变量的默认值,内容如下: #if defined(CONFIG_SYS_BOOT_NAND) #define CONFIG_EXTRA_ENV_SETTINGS CONFIG_MFG_ENV_SETTINGS panel=TFT43AB fdt_addr=0x83000000 fdt_high=0xffff
[单片机]
【<font color='red'>IMX6ULL</font>学习笔记】六、<font color='red'>U-BOOT</font><font color='red'>环境变量</font>与<font color='red'>Linux</font><font color='red'>启动</font>
mini2440 u-boot linux 内核启动,u-boot.2012.10——mini2440(二、启动流程分析)
参考资料:https://blog.csdn.net/suiyuan19840208/article/details/7239949 https://blog.csdn.net/pugu12/article/details/47011159 http://tscsh.blog.163.com/blog/static/200320103201312645149965/ https://blog.csdn.net/winheroii58/article/details/6803327 1、第一阶段功能 * 硬件设备初始化 * 加载u-boot第二段代码到RAM空间 * 设置好栈 * 跳转到第二段代码入口 2、第二段代码的功能 * 初始
[单片机]
mini2440 <font color='red'>u-boot</font> <font color='red'>linux</font> 内核<font color='red'>启动</font>,u-boot.2012.10——mini2440(二、<font color='red'>启动</font>流程分析)
IMX6ULL学习笔记(7)——通过SD卡启动U-Boot
一、简介 在 Ubuntu 下可以更精细地操作 SD/TF 卡:可以把 sdcoard.img 整个烧写到卡上,也可以单独烧写 U-Boot 到卡上,甚至挂接卡上的文件系统后单独更新里面的文件。 常用于做 U-Boot 测试。 1.1 dd命令 主用功能是用于拷贝文件,也就是用指定大小的块去拷贝一个文件,并在拷贝的同时进行指定的转换(默认从标准输入拷贝到标准输出,这意味dd可以在管道中使用)。这个拷贝过程简单理解就是读取,转换并输出数据。 用法: dd 二、识别SD卡 首先 SD 卡插入读卡器,再把读卡器插入电脑。 VMWare 有时候会自动弹出对话框,选择 连接到虚拟机 即可。 如果没有对话框,可以通过
[单片机]
ARM-Linux开机自启动设置-mini2440开发板
要在开发板上的Linux开机启动自己的程序,想着简单,却改了很久,绕了一圈下来确实很简单,只是自己一开始太过迂腐吧! 如果不想看完全文,这一段应该就够了,从我使用的开发板的角度讲,一般只要在/etc/init.d/rcS中加入你的程序或者脚本命令就可以实现开机自动运行;想在超级终端输入回车,登录后执行,则可以在/etc/profile中加入命令;如果想去掉每次开机完后的“Please press Enter to activate this console”这句,也就是实现开机自动登录,可以在/etc/inittab中仿照busybox中example的inittab写,只是将::askfirst:-/bin/sh改为::resp
[单片机]
OK6410A 开发板 (八) 32 linux-5.11 OK6410A 从内存角度简略分析整个启动过程
从 arch/arm/kernel/head.S 中的 stext 到 内核 rest_init 的 system_state = SYSTEM_SCHEDULING; 分析 整个内存的启动过程 至于 为什么不分析 arch/arm/boot/compressed/head.S 中的start 到 arch/arm/kernel/head.S 中的 stext 因为 这个过程可以不跑的话, linux 也能运行起来 之前在 https://blog.csdn.net/u011011827/article/details/115944495 分析 过,此过程 跑不跑 带来的效果的是一样的 整个过程可以分段为5个阶段 A ar
[单片机]
迅为-i.MX6开发板手册更新-非设备树uboot-修改默认环境变量
本文档主要介绍如何非设备树 uboot 修改默认启动参数。iTOP-iMX6 开发板烧写好之后,默认是android 系统 9.7 寸屏幕的系统参数和屏幕参数,如下图所示。输入以下命令查看默认启动参数printenv 74.1 重要的环境变量 比较重要的环境变量或者说经常使用的环境变量,已经在上图中的红色方框中。 主要是:bootsystem、lcdtype 和 bootargs。这些参数都可以在 uboot 源码中进行设置。具体文件为:“iTOP-iMX6_android4.4.2/bootable/bootloader/uboot-imx/lib_arm/board.c”文件。 74.2 默认启动系统设置 默认启动系统参数是
[单片机]
迅为-i.MX6开发板手册更新-非设备树uboot-修改默认<font color='red'>环境变量</font>
迅为-IMX6Q开发-非设备树uboot-修改默认环境变量
iTOP-iMX6 开发板烧写好之后,默认是 android 系统 9.7 寸屏幕的系统参数和屏幕参数。如下图。本文档主要介绍如何修改默认启动参数。 70.1 重要的环境变量 比较重要的环境变量或者说经常使用的环境变量,已经在上图中的红色方框中。 主要是:bootsystem、lcdtype 和 bootargs。这些参数都可以在 uboot 源码中进行设置。具体文件为:“iTOP-iMX6_android4.4.2/bootable/bootloader/uboot-imx/lib_arm/board.c”文件。 70.2 默认启动系统设置 默认启动系统参数是:bootsystem。打开“board.c”文件。搜索关键词“b
[单片机]
迅为-IMX6Q开发-非设备树uboot-修改默认<font color='red'>环境变量</font>
Linux之ARM(IMX6U)裸机之I.MX6ULL镜像烧写及启动头文件的详解
前面我们设置好 BOOT 以后就能从指定的设备启动了,但是你的设备里面得有代码啊,在LED灯实验中我们使用 imxdownload 这个软件将 led.bin 烧写到了 SD 卡中。imxdownload 会在 led.bin前面添加一些头信息,重新生成一个叫做 load.imx 的文件,最终实际烧写的是 laod.imx。那么imxdownload 究竟做了什么? load.imx 和 led.bin 究竟是什么关系? ①、 Image vector table,简称 IVT, IVT 里面包含了一系列的地址信息,这些地址信息在ROM 中按照固定的地址存放着。 ②、 Boot data,启动数据,包含了镜像要拷贝到哪个地址,
[单片机]
<font color='red'>Linux</font>之ARM(IMX6U)裸机之I.MX6ULL镜像烧写及<font color='red'>启动</font>头文件的详解
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved