个人名片:
🎓作者简介:嵌入式领域优质创作者
🌐个人主页:妄北y📞个人QQ:2061314755
💌个人邮箱:[mailto:2061314755@qq.com]
📱个人微信:Vir2025WBY🖥️个人公众号:科技妄北
🖋️本文为妄北y原创佳作,独家首发于CSDN🎊🎊🎊
💡座右铭:改造世界固然伟大,但改造自我更为可贵。
专栏导航:
妄北y系列专栏导航:
物联网嵌入式开发项目:大学期间的毕业设计,课程设计,大创项目,各种竞赛项目,全面覆盖了需求分析、方案设计、实施与调试、成果展示以及总结反思等关键环节。📚💼💡
QT基础入门学习:对QT的基础图形化页面设计进行了一个简单的学习与认识,利用QT的基础知识进行了翻金币小游戏的制作。🛠️🔧💭
Linux基础编程:初步认识什么是Linux,为什么学Linux,安装环境,进行基础命令的学习,入门级的shell编程。🍻🎉🖥️
深耕Linux应用开发:分享Linux的基本概念、命令行操作、文件系统、用户和权限管理等,网络编程相关知识,TCP/IP 协议、套接字(Socket)编程等,可以实现网络通信功能。常见开源库的二次开发,如libcurl、OpenSSL、json-c、freetype等💐📝💡
Linux驱动开发:Linux驱动开发是Linux系统不可或缺的组成部分,它专注于编写特殊的程序——驱动程序。这些程序承载着硬件设备的详细信息,并扮演着操作系统与硬件间沟通的桥梁角色。驱动开发的核心使命在于确保硬件设备在Linux系统上顺畅运作,同时实现与操作系统的无缝集成,为用户带来流畅稳定的体验。🚀🔧💻
Linux项目开发:Linux基础知识的实践,做项目是最锻炼能力的一个学习方法,这里我们会学习到一些简单基础的项目开发与应用,而且都是毕业设计级别的哦。🤸🌱🚀
非常期待与您一同在这个广阔的互联网天地里,携手探索知识的海洋,互相学习,共同进步。🌐💫🌱 熠熠星光,照亮我们的成长之路
✨✨ 欢迎订阅本专栏,对专栏内容任何问题都可以随时联系博主,共同书写属于我们的精彩篇章!✨✨
文章介绍:
📚本篇文章将深入剖析U-Boot基础学习的精髓与奥秘,与您一同分享相关知识!🎉🎉🎉
若您觉得文章尚可入目,期待您能慷慨地送上点赞、收藏与分享的三连支持!您的每一份鼓励,都是我创作路上源源不断的动力。让我们携手并进,共同奔跑,期待在顶峰相见的那一天,共庆辉煌!🚀🚀🚀
🙏衷心感谢大家的点赞👍、收藏⭐和评论✍️,您的支持是我前进的动力!
目录:
6.14.3. nand read addr off size
6.14.4. nand write addr off size
6.15.8. usb read addr blk# cnt
6.17.1.nm [.b, .w, .l] address
6.17.2. mm [.b, .w, .l] address
6.17.3. md [.b, .w, .l] address [# of objects]
6.17.4. mw [.b, .w, .l] address value [count]
6.17.5. cp [.b, .w, .l] source target count
7.4 load (tftp, fatload, ext2load, nfs):
一、Bootloader
1.1 什么是Bootloader
Bootloader 是一小段在操作系统启动前执行的程序。
它的主要功能是初始化硬件设备并配置内存映射,为操作系统内核的启动与运行创造必要的硬件和软件条件。这样做确保了系统在加载和执行操作系统内核之前,已经拥有了合适的运行环境。
1.2 Bootloader的种类
二、uboot
2.1 什么是uboot
Uboot,全称为Das U-Boot(通用引导加载程序),是一种开源的固件程序,主要用于嵌入式设备的引导过程。它支持多种处理器架构和硬件平台,功能包括初始化硬件设备、加载和运行操作系统等。Uboot通常被用于开发阶段和生产阶段,为设备提供灵活的引导选项和调试功能。
2.2 Uboot对硬件平台的支持
U-Boot,即通用引导加载程序,是一款广泛应用于嵌入式系统的开源引导加载程序。它支持多种处理器架构,包括但不限于PowerPC (PPC)、ARM、AVR32、MIPS、x86、68k、Nios和MicroBlaze等系列处理器。U-Boot的功能强大,能够初始化硬件、加载操作系统,并为嵌入式设备提供灵活的引导和调试选项。
U-Boot作为一款功能强大的引导加载程序,不仅限于支持嵌入式Linux系统的引导,它还广泛兼容多种操作系统。目前,U-Boot支持的目标操作系统包括但不限于OpenBSD、NetBSD、FreeBSD、4.4BSD、Linux、SVR4、Esix、Solaris、Irix、SCO、Dell、NCR、VxWorks、LynxOS、pSoS、QNX、RTEMS、ARTOS和Android等。这种广泛的兼容性使得U-Boot成为嵌入式系统开发中一个非常受欢迎的选择。
三、嵌入式启动流程
3.1 第一阶段:引导前的初始化
-
设备上电之后:设备上电后,首先执行的是芯片内置的ROM(iROM)中的出厂代码。这部分代码负责基本的硬件检测和初始化,并且决定从哪个设备(如NAND闪存、SD卡等)加载引导程序。
-
执行U-Boot:接着,系统根据iROM中的代码指示,从指定的启动设备中加载U-Boot引导程序(在这个案例中是
u-boot-iTOP-4412.bin
文件)。这个阶段U-Boot会进行自己的初始化,包括设置系统时钟、初始化内存控制器、配置网络等外设。
3.2 第二阶段:加载和启动操作系统
-
启动Linux内核:U-Boot根据配置或者命令,从存储介质中找到并加载Linux内核(
uImage
)。在这个过程中,它可能还会加载设备树二进制文件(itop-elite.dtb
),设备树用于描述硬件设备信息,以便内核知道硬件的配置。 -
挂载文件系统:内核加载并初始化后,会根据U-Boot传递的参数找到并挂载根文件系统(
rootfs
),这可能是一个嵌入式文件系统或者更传统的磁盘分区。 -
执行应用程序:一旦文件系统挂载完毕,系统会启动第一个用户空间程序。在许多Linux系统中,这通常是
init
或者类似的初始化程序。在某些情况下,特别是在嵌入式系统中,这可能是一个特定的脚本或程序,如linuxrc
。
四、存储的镜像有哪些外设?
在嵌入式系统中,有多种方式来加载和更新软件,包括操作系统镜像和其他关键数据。这些方法不仅包括传统的存储介质,还包括通过网络和其他接口进行的直接数据传输。
在嵌入式系统中,有多种方式来加载和更新软件,包括操作系统镜像和其他关键数据。这些方法不仅包括传统的存储介质,还包括通过网络和其他接口进行的直接数据传输。下面是您提到的各种加载方式的详细说明:
4.1 网络 - TFTP:
TFTP(Trivial File Transfer Protocol,简单文件传输协议)是一种广泛使用的轻量级协议,常用于局域网环境中无盘工作站的引导和嵌入式设备的固件更新。它允许设备在启动时从网络服务器下载文件,如操作系统镜像。
4.2 串口 - loadb + Kermit:
通过串口使用Kermit协议进行文件传输。这是一种早期的通信协议,支持错误检查和文件传输。`loadb`是U-Boot命令,用于通过串口接收数据。结合Kermit协议,它可以安全地通过串口加载操作系统镜像或其他数据。
4.3 USB - Fastboot:
Fastboot是一个诊断协议,主要用于与设备的bootloader交互,以便快速更新设备上的软件。它通常用于开发阶段,允许开发者通过USB接口直接加载和写入设备存储。
4.4 JLink/JTAG:
JLink和JTAG(Joint Test Action Group)接口常用于调试和编程微控制器和其他电子硬件。这些工具允许开发者在硬件级别与设备通信,进行编程、调试、固件烧写等操作。
4.5 TF卡 - fatload:
TF卡(即微型SD卡)是一种常用的便携式存储设备。`fatload`是一个常见的U-Boot命令,用于从FAT(File Allocation Table)文件系统的存储设备(如TF卡)中加载文件。这种方法适用于从物理介质快速启动系统或更新数据。
每种方法都有其特定的应用场景和优点。例如,网络启动适合于快速部署和测试,串口和USB提供了直接的硬件级数据传输,而JLink/JTAG则是强大的硬件调试工具。TF卡提供了一种便携和易于交换的数据存储方式。根据具体的应用需求和开发环境,开发者可以选择最合适的加载方法。
六、Uboot常用命令
U-Boot(通用引导加载程序)是一个在嵌入式系统中非常普遍的启动加载程序。它支持多种硬件平台,提供了丰富的命令来帮助初始化硬件设备、加载和启动操作系统等。
6.1 bootd (或 boot):
启动操作系统。默认情况下,该命令会按照 `bootcmd` 环境变量中定义的命令来启动系统。
6.2 reset:
在 U-Boot 命令提示符下,简单输入 reset
并按回车键,就可以立即重启系统:
reset
6.3 bdinfo:
用于显示当前开发板(Board)的详细信息。这个命令通常会提供关于硬件配置、内存布局、启动参数等方面的信息,对于调试和了解系统状态非常有用。
执行 bdinfo
命令后,您可能会看到类似以下的信息:
arch_number = 0x00000000
boot_params = 0x10000100
DRAM bank = 0x00000000
-> start = 0x00000000
-> size = 0x20000000
baudrate = 115200 bps
TLB addr = 0x20000000
relocaddr = 0x10000000
reloc off = 0x00000000
irq_sp = 0x00000000
sp start = 0x00000000
FB base = 0x00000000
这些信息的具体内容会根据您的开发板和配置有所不同。以下是一些常见的输出项解释:
- arch_number: 架构编号,表示处理器的类型。
- boot_params: 启动参数的内存地址,通常是内核启动时传递参数的位置。
- DRAM bank: 动态随机存取存储器(DRAM)的配置,包括起始地址和大小。
- baudrate: 当前使用的串口波特率。
- TLB addr: 转换后备缓冲区(Translation Lookaside Buffer)的地址。
- relocaddr: U-Boot 重定位后的地址。
- reloc off: U-Boot 重定位的偏移量。
- irq_sp: 中断服务例程(ISR)使用的堆栈指针。
- sp start: 堆栈的起始地址。
- FB base: 帧缓冲(Frame Buffer)的基地址,用于图形显示。
6.9 version:
version
命令通常用于显示当前 bootloader 的版本信息。这包括版本号、构建日期、构建环境以及可能的额外信息,如支持的硬件或特殊功能。
输出示例
执行 version
命令后,输出可能类似于以下内容(具体输出会根据您的 U-Boot 版本和构建配置而有所不同):
U-Boot 2023.01 (Mar 03 2023 - 14:55:16 +0000)
arm-poky-linux-gnueabi-gcc (GCC) 10.2.0
GNU ld (GNU Binutils) 2.34
此输出显示了 U-Boot 的版本号(2023.01),编译日期和时间(Mar 03 2023 - 14:55:16 +0000),以及用于编译 U-Boot 的工具链版本信息。
6.10 help:
在 U-Boot 提示符下,help
命令可以提供关于可用命令及其简短描述的列表,这对于了解你可以执行哪些操作非常有帮助。这个命令在你不熟悉 U-Boot 的命令集或需要快速查找特定命令的用途时尤其有用。
运行 help
命令通常会显示类似以下的输出(注意,实际显示的命令和详情可能会根据 U-Boot 的版本和配置有所不同):
U-Boot> help
? - alias for 'help'
base - print or set address offset
bdinfo - print Board Info structure
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
cmp - memory compare
cp - memory copy
crc32 - checksum calculation
echo - echo args to console
editenv - edit environment variable
exit - exit script
false - do nothing, unsuccessfully
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
go - start application at address 'addr'
help - print command description/usage
i2c - I2C sub-system
loop - infinite loop on address range
md - memory display
mm - memory modify (auto-incrementing address)
...
- 基本命令: 如
boot
(启动系统),reset
(重置系统),saveenv
(保存环境变量) 等。- 网络命令: 如
ping
,dhcp
,tftpboot
(通过网络启动)。- 内存和存储操作: 如
md
(内存显示),mm
(内存修改),cp
(内存拷贝)。- 文件系统操作: 如
fatls
,fatload
(从 FAT 文件系统加载文件)。- 环境变量操作: 如
setenv
,printenv
(设置和显示环境变量)。
6.11 run
run
命令用于执行存储在环境变量中的命令序列。这个功能特别有用,因为它允许用户预定义复杂的操作序列,并在需要时通过简单的命令调用来执行这些操作。
假设你已经定义了一个环境变量 my_script
,其中包含一系列命令,例如:
U-Boot> setenv my_script 'echo Starting script...; fatload mmc 0:1 0x20000000 my_image.bin; bootm 0x20000000'
这个脚本首先输出一条消息,然后从 MMC 卡加载一个二进制文件到内存,并最终启动这个映像。你可以通过以下命令来运行这个脚本:
U-Boot> run my_script
执行上述命令后,U-Boot 将依次执行 my_script
环境变量中定义的所有命令。
6.12 go:
go
命令是一个用于直接跳转到指定内存地址并开始执行代码的命令。这个命令通常用于调试目的,或者在您已经手动加载了内核或引导程序到内存中时使用。
go <address> #<address> 是您希望开始执行的内存地址
假设您已经将一个引导程序加载到内存地址 0x80000000
,您可以使用以下命令来启动它:
go 0x80000000
6.13 网络命令:
6.13.1 ping
- 含义: 测试网络连接是否可用。
- 用法:
ping <ip_address>
- 示例:
ping 192.168.1.1
- 描述: 此命令发送 ICMP Echo请求到指定的 IP 地址,并等待回应。它用于验证设备是否能够看到并与网络上的其他设备通信。
6.13.2 dhcp
- 含义: 动态主机配置协议(DHCP)客户端,用于自动从DHCP服务器获取IP地址及其他网络设置。
- 用法:
dhcp
- 示例:
dhcp
- 描述: 执行此命令会使设备尝试从连接的网络中的 DHCP 服务器获取 IP 地址、子网掩码、默认网关和其他相关的网络配置信息。
6.13.3 nfs
- 含义: 使用网络文件系统(NFS)从服务器加载文件到内存中。
- 用法:
nfs <memory_address> <server_ip>:<file_path>
- 示例:
nfs 0x80000000 192.168.1.2:/path/to/image
- 描述: 此命令允许从指定的 NFS 服务器下载文件直接到内存中。这在没有本地存储介质,或者希望从远程服务器加载操作系统映像或数据时非常有用。
6.13.4 tftp
- 含义: 通过网络使用简单文件传输协议(TFTP)下载文件到内存中。
- 用法:
tftp <memory_address> <file_name>
- 示例:
tftp 0x80000000 uImage
- 描述: TFTP 是一个简单的协议,常用于在局域网络中传输文件。此命令用于从 TFTP 服务器下载文件到指定的内存地址。常见用途包括加载内核映像或其他启动文件。
6.14 Nand Flash命令:
6.14.1.nand info
- 含义: 显示当前可用的 NAND Flash 设备的信息。
- 用法:
nand info
- 示例:
nand info
- 描述: 此命令输出有关连接到系统的 NAND Flash 设备的信息,包括设备的大小、块大小、页大小等。
6.14.2. nand device [dev]
- 含义: 选择或切换当前操作的 NAND Flash 设备。
- 用法:
nand device [dev]
- 示例:
nand device 0
- 描述: 如果你的系统支持多个 NAND Flash 设备,可以使用此命令来指定当前操作的设备。
dev
参数指定设备编号。
6.14.3. nand read addr off size
- 含义: 从 NAND Flash 的指定偏移地址读取数据到内存。
- 用法:
nand read <addr> <off> <size>
- 示例:
nand read 0x20000000 0x0 0x400000
- 描述: 此命令从 NAND Flash 的偏移地址
off
开始读取size
字节的数据,并将其存储到内存地址addr
。这在加载引导加载程序、内核或文件系统时非常有用。
6.14.4. nand write addr off size
- 含义: 将内存中的数据写入到 NAND Flash 的指定偏移地址。
- 用法:
nand write <addr> <off> <size>
- 示例:
nand write 0x20000000 0x0 0x400000
- 描述: 此命令将内存地址
addr
处的size
字节数据写入到 NAND Flash 的偏移地址off
。这在更新引导加载程序、内核或文件系统时非常有用。
6.15 USB操作命令:
6.15.1usb reset
- 含义: 初始化USB控制器。
- 用法:
usb reset
- 描述: 此命令重新初始化USB子系统和控制器,使所有连接的USB设备重新枚举。这通常是在尝试识别或使用USB设备之前需要执行的第一步。
6.15.
2. usb stop [f]
- 含义: 关闭USB控制器。
- 用法:
usb stop [f]
- 描述: 此命令关闭USB子系统。可选参数
[f]
可用于强制停止操作,即使有些操作(如数据传输)正在进行。
6.15.
3. usb tree
- 含义: 显示已连接的USB设备树。
- 用法:
usb tree
- 描述: 此命令以树状结构显示系统上已识别的USB设备及其连接方式。这有助于识别设备的物理连接布局。
6.15.
4. usb info [dev]
- 含义: 显示USB设备[dev]的信息。
- 用法:
usb info [dev]
- 描述: 如果提供了
[dev]
参数,则此命令显示特定USB设备的详细信息。如果未提供,它将显示所有已识别USB设备的信息。
6.15.
5. usb storage
- 含义: 显示已连接的USB存储设备。
- 用法:
usb storage
- 描述: 此命令列出所有已识别的USB存储设备。这对于确认U-Boot是否已成功识别外部USB驱动器非常有用。
6.15.
6. usb dev [dev]
- 含义: 显示和设置当前USB存储设备。
- 用法:
usb dev [dev]
- 描述: 如果提供了
[dev]
参数,该命令设置当前的USB存储设备至指定设备。没有参数时,它显示当前选择的USB存储设备信息。
6.15.
7. usb part [dev]
- 含义: 显示USB存储设备[dev]的分区信息。
- 用法:
usb part [dev]
- 描述: 此命令显示指定USB存储设备的分区布局。这对于了解设备上的数据结构和执行针对特定分区的操作非常有用。
6.15.
8. usb read addr blk# cnt
- 含义: 从USB存储设备读取数据。
- 用法:
usb read <addr> <blk#> <cnt>
- 描述: 此命令从USB存储设备读取指定数量的块(
cnt
)到内存地址(addr
),从块号(blk#
)开始。这是加载数据或系统映像到内存的常见方法。
6.16 mmc:
执行与MMC/SD卡相关的操作,如 `mmc info`, `mmc read`, `mmc write` 等。
6.16.1. mmc info
- 含义: 显示当前 MMC/SD 卡的信息。
- 用法:
mmc info
- 示例:
mmc info
- 描述: 此命令输出有关当前选择的 MMC/SD 卡的信息,包括卡的类型、容量、分区等详细信息。
6.16.2. mmc read
- 含义: 从 MMC/SD 卡读取数据到内存。
- 用法:
mmc read <addr> <blk#> <cnt>
- 示例:
mmc read 0x80000000 0x100 0x200
- 描述: 从 MMC/SD 卡的指定块号(
blk#
)开始读取指定数量的块(cnt
)到内存地址(addr
)。这在加载文件系统、内核映像或其他数据时非常有用。
6.16.3. mmc write
- 含义: 将内存中的数据写入到 MMC/SD 卡。
- 用法:
mmc write <addr> <blk#> <cnt>
- 示例:
mmc write 0x80000000 0x100 0x200
- 描述: 将内存地址(
addr
)处的指定数量的块(cnt
)写入到 MMC/SD 卡的指定块号(blk#
)。这在更新文件系统、内核映像或存储其他数据时非常有用。
6.16.4. mmc rescan
- 含义: 重新扫描 MMC/SD 卡。
- 用法:
mmc rescan
- 示例:
mmc rescan
- 描述: 重新扫描 MMC/SD 卡接口,以检测插入或移除的卡。这在更换卡之后或系统启动时确认卡的存在非常有用。
6.16.5. mmc part
- 含义: 显示 MMC/SD 卡的分区信息。
- 用法:
mmc part
- 示例:
mmc part
- 描述: 此命令显示当前 MMC/SD 卡的分区布局,包括每个分区的起始地址、大小和类型等信息。
6.17 内存寄存器操作命令:
6.17.1.nm [.b, .w, .l] address
- 含义: 修改指定地址
address
的内存值。 - 用法:
nm [.b, .w, .l] address
- 描述: 此命令允许用户修改一个内存地址的值。用户可以选择操作的大小:字节(
.b
)、字(.w
)、或长字(.l
)。命令执行后,会提示用户输入一个新值。
6.17.
2. mm [.b, .w, .l] address
- 含义: 修改指定地址
address
内存值(地址自动加一)。 - 用法:
mm [.b, .w, .l] address
- 描述: 与
nm
命令类似,不过在每次修改后,地址自动增加以指向下一个单元(根据操作的大小)。这对于连续写入多个内存位置非常有用。
6.17.
3. md [.b, .w, .l] address [# of objects]
- 含义: 显示地址
address
开始的内存值,[#of objects]
表示要查看的数据长度。 - 用法:
md [.b, .w, .l] address [# of objects]
- 描述: 此命令用于读取并显示内存地址开始的一系列值。用户可以指定读取的对象数以及每个对象的大小(字节、字或长字)。
6.17.
4. mw [.b, .w, .l] address value [count]
- 含义: 用指定的数据
value
填充内存,起始地址为address
,填充count
个数据块。 - 用法:
mw [.b, .w, .l] address value [count]
- 描述: 此命令将给定的
value
重复写入内存中count
次。如果未指定count
,默认为1。这个命令很有用,例如,用特定模式初始化一段内存区域。
6.17.
5. cp [.b, .w, .l] source target count
- 含义: 数据拷贝命令,用于将DRAM中的数据从一段内存拷贝到另一段内存中,或者把Nor Flash中的数据拷贝到DRAM中。
- 用法:
cp [.b, .w, .l] source target count
- 描述: 此命令允许用户按指定的单位(字节、字、或长字)拷贝一定数量(
count
)的数据从源地址(source
)到目标地址(target
)。这在进行内存内容迁移或备份时非常有用。
七、其他重要命令
7.1 saveenv:
保存环境变量到持久存储设备上。
7.2 printenv (或 env print):
显示所有环境变量或指定的环境变量。
例: `printenv bootcmd` 显示 `bootcamp` 变量的值。
7.3 setenv:
设置环境变量。
例: `setenv bootargs root=/dev/ram rw` 设置 `bootargs`。
7.4 load (tftp, fatload, ext2load, nfs):
从不同的源加载数据到内存。例如,`tftp` 从TFTP服务器加载,`fatload` 从FAT文件系统加载,等等。
7.5 iminfo:
显示内存中的映像信息。
7.6 bootm:
启动内存中的应用程序。通常用于启动内存中的Linux内核。
7.7 spi:
执行与 SPI 相关的操作,比如读写 SPI 闪存。
7.8 usb start/stop:
启动或停止 USB 子系统。这对于从 USB 设备启动或读取数据非常有用。
7.9 dhcp:
使用 DHCP 协议获取 IP 地址,并且可以通过网络启动系统。
7.10 mw (memory write):
向指定的内存地址写数据。可以用于修改内存中的特定值。
7.11. cp (copy):
在内存中复制数据从一个位置到另一个位置。
7.12 cmp (compare):
比较内存中两个区域的内容,检查是否相同。
7.13 crc32:
计算指定内存区域的 CRC32 校验和。这可以用于验证数据的完整性。
7.14 tftpboot:
通过 TFTP 协议加载文件到内存,并准备启动。这是网络启动的一种常见方式。
7.15 bootp:
使用 BOOTP 协议获取网络启动的配置,如 IP 地址、服务器地址和文件名。
7.16 editenv:
编辑环境变量。这允许用户直接修改环境变量的值。
📝大佬觉得本文有所裨益,不妨轻点一下👍给予鼓励吧!
❤️❤️❤️本人虽努力,但能力尚浅,若有不足之处,恳请各位大佬不吝赐教,您的批评指正将是我进步的动力!😊😊😊
💖💖💖若您认为此篇文章对您有所帮助,烦请点赞👍并收藏🌟,您的支持是我前行的最大动力!
🚀🚀🚀任务在默默中完成,价值在悄然间提升。让我们携手共进,一起加油,迎接更美好的未来!🌈🌈🌈