文章目录
- 一、bootcmd环境变量
- 二、bootargs环境变量
- 1.console
- 2.root
- 三.uboot启动Linux测试
- 方式1:从 EMMC 启动 Linux 系统
- 方式2:从网络启动 Linux 系统
一、bootcmd环境变量
💦boot 中有两个非常重要的环境变量 bootcmd 和 bootargs。bootcmd 和 bootagrs 是采用类似 shell 脚本语言编写的,里面有很多的变量引用,这些变量其实都是环境变量,有很多是 NXP 自 己 定 义 的 。 文 件 mx6ull_alientek_emmc.h 中CONFIG_EXTRA_ENV_SETTINGS 保存着这些环境变量的默认值。
💦bootcmd 保存着 uboot 默认命令,uboot 倒计时结束以后就会执行 bootcmd 中的命令。这些命令一般都是用来启动 Linux 内核的,比如读取 EMMC 或者 NAND Flash 中的 Linux 内核镜像文件和设备树文件到 DRAM 中,然后启动 Linux 内核。可以在 uboot 启动以后进入命令行设置 bootcmd 环境变量的值。如果 EMMC 或者 NAND 中没有保存 bootcmd 的值,那么 uboot 就会使用默认的值,板子第一次运行 uboot 的时候都会使用默认值来设置 bootcmd 环境变量。打开文件 include/env_default.h,在此文件中有如下所示内容。
💦如此复杂的设置就是为了从 EMMC 中读取 zImage 镜像文件和设备树文件,启动 Linux 内核。
💦精简后命令如下:
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
💦NXP 官方将 CONFIG_BOOTCOMMAND 写的这么复杂只有一个目的:为了兼容多个板子,所以写了个很复杂的脚本。当我们明确知道我们所使用的板子的时候就可以大幅简化宏
CONFIG_BOOTCOMMAND 的 设 置 , 比 如 我 们 要 从 EMMC 启动,那么宏
CONFIG_BOOTCOMMAND 就可简化为:
#define CONFIG_BOOTCOMMAND \"mmc dev 1;" \"fatload mmc 1:1 0x80800000 zImage;" \"fatload mmc 1:1 0x83000000 imx6ull-alientek-emmc.dtb;" \"bootz 0x80800000 - 0x83000000;"
或者可以直接在 uboot 中设置 bootcmd 的值,这个值就是保存到 EMMC 中的
setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000 imx6ull-alientek-emmc.dtb; bootz 80800000 - 83000000;'
二、bootargs环境变量
💦bootargs 保存着 uboot 传递给 Linux 内核的参数,
💦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 终端,这样我们就可以在电脑上通过Xshell 来和 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 的话可能无法在根文件系统中进行写操作,只能进行读操作。
三.uboot启动Linux测试
方式1:从 EMMC 启动 Linux 系统
💦从 EMMC 启动也就是将编译出来的 Linux 镜像文件 zImage 和设备树文件保存在 EMMC
中,uboot 从 EMMC 中读取这两个文件并启动,这个是我们产品最终的启动方式。先检查一下 EMMC 的分区 1 中有没有zImage 文件和设备树文件
💦从上可以看出, EMMC 分区 1 中存在 zimage 和 imx6ull-alientek-emmc.dtb
这两个文件,所以我们可以测试新移植的 uboot 能不能启动 linux 内核。设置 bootargs 和 bootcmd这两个环境变量,设置如下:
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000
imx6ull-14x14-emmc-4.3-800x480-c.dtb; bootz 80800000 - 83000000;'
saveenv //boot //启动内核
方式2:从网络启动 Linux 系统
💦从网络启动 linux 系统的唯一目的就是为了调试!不管是为了调试 linux 系统还是 linux 下的驱动。每次修改 linux 系统文件或者 linux 下的某个驱动以后都要将其烧写到 EMMC 中去测试,这样太麻烦了。我们可以设置 linux 从网络启动,也就是将 linux 镜像文件和根文件系统都放到 Ubuntu 下某个指定的文件夹中,这样每次重新编译 linux 内核或者某个 linux 驱动以后只需要使用 cp 命令将其拷贝到这个指定的文件夹中即可,这样就不用需要频繁的烧写 EMMC,这样就加快了开发速度。我们可以通过 nfs 或者 tftp 从 Ubuntu 中下载 zImage 和设备树文件,根文件系统的话也可以通过 nfs 挂载,这里我们使用 tftp 从 Ubuntu 中下载 zImage 和设备树文件,前提是要将 zImage 和设备树文件放到 Ubuntu 下的 tftp 目录中,
设置 bootargs 和 bootcmd 这两个环境变量,设置如下:
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-14x14-emmc-4.3-800x480-c.dtb; bootz 80800000 - 83000000'
saveenv
boot