U-boot引导Linux内核启动

一、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)
相关推荐
桑榆肖物11 分钟前
.NET 10 Native AOT 在 Linux 嵌入式设备上的实战
java·linux·.net·aot
YMWM_13 分钟前
磁盘的分区格式MBR和GPT的区别
linux·磁盘分区
春日见30 分钟前
端到端自动驾驶综述
linux·人工智能·算法·机器学习·自动驾驶
Trouvaille ~1 小时前
【项目篇】从零手写高并发服务器(六):EventLoop事件循环——Reactor的心脏
linux·运维·服务器·c++·高并发·epoll·reactor模式
bai_lan_ya1 小时前
linux -- 文件IO
linux·服务器
林鸿群1 小时前
Ubuntu 26.04 本地安装 GitLab CE 完整教程(非 Docker 方式)
linux·ubuntu·gitlab·私有部署·代码托管·ubuntu 26.04·omnibus
勇闯逆流河1 小时前
【Linux】Linux进程概念(进程优先级,进程切换详解)
linux·运维·服务器
老师好,我是刘同学1 小时前
30个核心Linux命令速查手册
linux
fsj2009yx1 小时前
如何把无公网的求生之路2服务器借助VPS转发注册到steam master列表中
linux·wireguard·求生之路2
慵懒的猫mi1 小时前
deepin UOS AI 助手接入飞书(Feishu)配置指南
linux·人工智能·ai·gpt-3·飞书·文心一言·deepin