一、U-boot
U-Boot,全称 Universal Boot Loader,是一个广泛应用于嵌入式系统的开源引导加载程序(Boot Loader),它支持多种不同架构的处理器,如 ARM、PowerPC、MIPS、x86 等,能够在各种嵌入式设备上运行,包括开发板、工业控制计算机、智能家居设备等
其主要作用为初始化硬件设备,引导操作系统的启动
二、U-boot基础命令介绍
帮助命令
显示u_boot支持的所有命令
进入 uboot 的命令行模式以后输入"help"或者"?",然后按下回车即可查看当前uboot所支持的命令

查看单个命令的详细用法
输入"help(或?) 命令名"就可以查看命令的详细用法

常用的与信息查询有关的命令有2个: bdinfo 和 version
bdinfo命令用于显示板级信息

version用于查看uboot的版本信息

环境变量命令
- printenv输出环境变量的值
- setenv设置环境变量
- saveenv保存环境变量
三、U-boot网络通信参数设置及ping命令
网络参数的设置

要求:
1、 开发板通过网线连接到路由器【ubuntu连接的路由器】或 开发板通过网线与ubuntu直连
2、虚拟机网络设置为"桥接模式"
ping命令
测试开发板的网络通信功能是否正常,是否可以和服务器(Ubuntu主机)进行通信,通过ping命令就可以验证,直接ping服务器的 IP 地址即可。比如我的服务器 IP地址为 192.168.0.104,命令如下:
cpp
=> ping 192.168.0.104
Using FEC0 device
host 192.168.0.104 is alive(与主机192.168.0.104通信正常)
四、TFTP服务和NFS服务使用
TFTP服务:TFTP(Trivial File Transfer Protocol)即简单文件传输协议 ,是TCP/IP协议族中用于在客户机与服务器间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务,端口号为69
4.1 tftp服务安装与卸载
cpp
sudo apt-get install tftp-hpa (客户端程序)
sudo apt-get install tftpd-hpa (服务端程序)
4.2 修改tftp配置文件
用管理员权限打开配置文件
cpp
sudo vi /etc/default/tftpd-hpa
TFTP_DIRECTORY="/home/linux/imx6ull_dev/tftp_workdir"
4.3 重启tftp服务
cpp
sudo /etc/init.d/tftpd-hpa restart
或
sudo service tftpd-hpa restart
4.4 测试tftp服务
cpp
linux@linux-virtual-machine:~$ tftp 192.168.0.104
tftp> get tftp.png
tftp> quit
五、NFS服务
NFS(Network File System)即网络文件系统 ,由Sun公司开发,是一种用于分布式文件系统的协议。它允许不同机器、不同操作系统通过网络共享数据,应用程序能像访问本地文件一样访问服务器磁盘中的数据。
典型应用:云存储(网盘)
如果缺少这些配置:
- 不指定目录路径 → NFS 无共享目录可提供;
- 不写
rw→ 客户端只能读,无法修改根文件系统文件;- 不写
no_root_squash→ 开发板 root 用户操作共享目录会报 "权限拒绝",无法正常启动系统
5.1 nfs服务安装与下载
cpp
在线安装:
sudo apt-get install nfs-kernel-server
卸载服务:
sudo apt remove --purge nfs-kernel-server
cpp
修改默认的配置文件:sudo vi /etc/exports
添加Ubuntu上需要共享的目录路径
/home/linux/imx6ull_dev/nfs/rootfs *(rw,sync,no_root_squash)
5.2 重启nfs服务
cpp
sudo /etc/init.d/nfs-kernel-server restart
或
sudo service nfs-kernel-server restart
5.3 测试nfs服务
创建挂载点目录(建议是空目录)
测试:
sudo mount IP:共享路径 自己的挂载点目录
例如:
sudo mount 192.168.0.104:/home/linux/imx6ull_dev/nfs/rootfs ./mountpoint (自己电脑上当前目录下的mountpoint子目录)
5.4 撤销挂载点
cpp
sudo umount 挂载点目录
例如:sudo umount ./mountpoint
六、U-boot网络方式引导Linux内核启动
通过tftp下载Linux内核启动需要的镜像文件,然后引导Linux内核启动
6.1 手动下载
cpp
下载:
tftp 80800000 zImage
tftp 83800000 imx6ull-14x14-emmc-4.3-800x480-c.dtb
tftp 81800000 ramdisk.img
zImage介绍:
Linux内核,操作系统镜像文件
smartcar_emmc_4_3.dtb:
设备树文件,存放的是硬件设备的信息,Linux内核在启动的时候会解析这个文件,识别当前的硬件设备
ramdisk介绍:
ramdisk即虚拟内存盘,它是通过软件将一部分内存(RAM)模拟为硬盘来使用的一种技术。
相对于直接的硬盘文件访问来说,这种技术可以极大的提高在其上进行的文件访问的速度
查看ramdisk.img信息:
安装u-boot-tools:
sudo apt install u-boot-tools
linux@linux-virtual-machine:~/imx6ull_dev/tftp_workdir$ mkimage -l ramdisk.img
Image Name: ramdisk
Created: Sat Mar 4 13:42:10 2023
Image Type: ARM Linux RAMDisk Image (uncompressed)
Data Size: 18874665 Bytes = 18432.29 KiB = 18.00 MiB
Load Address: 81800000
Entry Point: 81800000

DRAM 起始地址(0x80000000)图中DRAM bank -> start = 0x80000000,这正是 imx6ull DDR 内存的物理起始地址,而你之前用的80800000(zImage 地址)、**81800000(ramdisk 地址)**都是基于这个起始地址 "偏移" 得到的(避开了 U-Boot 占用的0x80000000~0x80800000区域)
DRAM 起始地址和大小,是83800000这个 dtb 下载地址合法可用的前提
我们在用tftp下载的时候,临时关闭ubuntu的防火墙 sudo ufw disable
6.2 引导Linux内核启动
设置u-boot环境变量
cpp
bootargs参数在u-boot引导Linux内核启动的时候会传递给Linux内核,告诉内核在启动的时候需要注意信
息
setenv bootargs 'console=ttymxc0,115200 ramdisk_size=12000000 rootfstype=ext2
rootwait rw'
console=ttymxc0,115200 告诉Linux内核在启动的时候使用串口1输出,波特率是115200
ramdisk_size=12000000 告诉Linux内核ramdisk镜像大小为0x12000000 byte = 128MB
rootfstype=ext2 告诉Linux内核ramdisk镜像使用的文件系统类型是ext2
rootwait 告诉Linux内核加载完所有驱动模块后在挂载文件系统
rw 告诉Linux内核在挂载完ramdisk以后可以对它进行读写
引导Linux内核启动
cpp
bootz [addr [initrd[:size]] [fdt]]
命令bootz 有三个参数:
addr 是Linux镜像文件在 DRAM 中的位置
initrd 是initrd文件在DRAM 中的地址,如果不使用 initrd 的话使用'-'代替即可
fdt 是设备树文件在 DRAM 中的地址
bootz 80800000 81800000 83800000
自动下载,然后启动Linux内核启动
cpp
setenv bootcmd 'tftp 80800000 zImage; tftp 83800000 imx6ull-14x14-emmc-4.3-800x480- c.dtb; bootz 80800000 - 83800000'
setenv bootargs console=ttymxc0,115200 root=/dev/nfs rw ip=dhcp nfsroot=192.168.0.105:/home/linux/imx6ull_dev/nfs/rootfs,v3,tcp
|------------------------------------------------------|-----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| setenv bootcmd '...' | 给 U-Boot 的bootcmd变量赋值,覆盖默认启动流程 | setenv是 U-Boot 中 "设置环境变量" 的命令 |
| tftp 80800000 zImage | 通过 TFTP 协议,从 TFTP 服务器下载内核镜像zImage到开发板物理内存地址0x80800000 | ① tftp:基于 UDP 的简单文件传输协议,需开发板与 TFTP 服务器(Ubuntu)同网段;② 80800000:内核镜像的加载地址(避开 U-Boot 占用的0x80000000~0x80800000);③ zImage:ARM 架构的压缩内核镜像(imx6ull 专用) |
| tftp 83800000 imx6ull-14x14-emmc-4.3-800x480-c.dtb | 通过 TFTP 下载设备树文件(dtb)到内存地址0x83800000 | ① dtb文件:内核识别硬件的 "硬件清单",该文件名对应:imx6ull 14x14 核心板 + eMMC+4.3 寸 800x480 屏幕的硬件配置;② 83800000:dtb 的加载地址(避开内核镜像占用的空间,防止重叠) |
| bootz 80800000 - 83800000 | 启动内核的核心命令(bootz专用于启动 zImage 格式内核) | ① bootz参数格式:bootz 内核地址 [ramdisk地址] dtb地址;② -:表示无 ramdisk(根文件系统用 NFS 挂载,无需内存磁盘);③ 执行该命令后,U-Boot 将控制权交给内核,内核开始初始化并挂载根文件系统 |
bootargs是 U-Boot 传递给 Linux 内核的 "启动参数",内核启动时会读取这些参数,确定串口、根文件系统、网络等关键配置。
| 参数片段 | 具体含义 | 关键细节 |
|---|---|---|
setenv bootargs '...' |
给 U-Boot 的bootargs变量赋值,传递给内核 |
内核启动时会解析该变量的所有参数,是内核初始化的核心依据 |
console=ttymxc0,115200 |
定义内核的控制台输出串口 | ① ttymxc0:imx6ull 的第一路串口(对应开发板的调试串口);② 115200:串口波特率(需与 U-Boot、串口工具波特率一致,否则乱码) |
root=/dev/nfs |
指定根文件系统类型为 NFS(网络文件系统) | 告诉内核:根文件系统不在本地 eMMC/SD 卡,而是通过 NFS 挂载的远程目录 |
rw |
根文件系统的访问权限:读写(Read-Write) | 若省略则默认只读(ro),开发板无法修改根文件系统文件(调试必设rw) |
ip=dhcp |
开发板内核启动后,通过 DHCP 自动获取 IP 地址 | 替代手动设置ipaddr:serverip:gateway,简化网络配置(需路由器 / DHCP 服务器分配 IP) |
nfsroot=192.168.0.105:/home/linux/imx6ull_dev/nfs/rootfs,v3,tcp |
定义 NFS 根文件系统的具体信息 | ① 192.168.0.105:NFS 服务器(Ubuntu)的 IP 地址;② /home/linux/imx6ull_dev/nfs/rootfs:Ubuntu 上共享的根文件系统目录(需与/etc/exports配置一致);③ v3:指定使用 NFSv3 版本(imx6ull 内核对 NFSv3 兼容性更好,避免 v4 挂载失败);④ tcp:使用 TCP 协议传输(NFS 默认用 UDP,TCP 更稳定,适合调试) |
如同nfs挂载文件目录一样
七、u_boot MMC设备相关操作命令
MMC命令介绍
u-boot 支持EMMC和SD卡,因此也要提供EMMC和SD卡的操作命令。一般认为EMMC和SD卡是同一个东西,所以没有特殊说明。mmc是一系列的命令,其后可以跟不同的参数,输入"? mmc"即可查看 mmc有关的命令:
cpp
=> ? mmc
mmc - MMC sub system
Usage:
mmc info - display info of the current MMC device
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] - show or set current mmc device [partition]
mmc list - lists available devices
mmc hwpartition [args...] - does hardware partitioning
arguments (sizes in 512-byte blocks):
[user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes
[gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition
[check|set|complete] - mode, complete set partitioning completed
WARNING: Partitioning is a write-once setting once it is set to complete.
Power cycling is required to initialize partitions after set to complete.
mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode
- Set the BOOT_BUS_WIDTH field of the specified device
mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>
- Change sizes of boot and RPMB partitions of specified device
mmc partconf dev boot_ack boot_partition partition_access
- Change the bits of the PARTITION_CONFIG field of the specified device
mmc rst-function dev value
- Change the RST_n_FUNCTION field of the specified device
WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.
mmc setdsr <value> - set DSR register value
显示存在的MMC设备
cpp
=> mmc list
FSL_SDHC: 0
FSL_SDHC: 1 (eMMC)
显示当前使用的MMC设备信息
bash
=> mmc info
Device: FSL_SDHC
Manufacturer ID: 15
OEM: 100
Name: 8GTF4 #设备名称为8GTF4,表明这是一款标称容量为8GB的TF(T-Flash,微型 SD)卡
Tran Speed: 52000000
Rd Block Len: 512 #读取块长度为512字节,这是存储设备进行数据读写时的基本块大小
MMC version 4.0
High Capacity: Yes #标识为大容量存储设备(SDHC),支持超过2GB的存储容量,符合SDHC规范。
Capacity: 7.3 GiB #实际可用容量为7.3GiB
Bus Width: 8-bit
Erase Group Size: 512 KiB #擦除组大小为512KiB,即设备进行擦除操作时的最小单位为512KiB
(512 × 1024 字节)
向MMC设备写数据
cpp
A、切换到emmc的第0分区
=> mmc dev 1 0
switch to partitions #0, OK
mmc1(part 0) is current device
B、从tftp下载u-boot.imx到内存80010000
=> tftp 80010000 u-boot.imx
FEC1 Waiting for PHY auto negotiation to complete.... done
Using FEC1 device
TFTP from server 192.168.0.105; our IP address is 192.168.0.110
Filename 'u-boot.imx'.
Load address: 0x80010000
Loading: #########################
57.6 KiB/s
done
Bytes transferred = 363520 (58c00 hex)