U-Boot学习(1):简介及命令行指令详解

news2025/1/18 17:14:25

Bootloader的主要任务是引导加载并运行应用程序,对于MCU中的BootLoader,我之前写过一篇详细的文章单片机中BootLoader的严谨实现详解介绍它实现的整体流程。对于Linux来说,在运行Linux内核之前也需要BootLoader进行引导,这个BootLoader不需要我们写,因为有很多开源代码供我们选择,其中最常用的就是U-Boot。这篇文章就来简单介绍以下U-Boot,来看一下它是怎么使用的。

文章目录

  • 1 U-Boot简介
  • 2 U-Boot命令行指令详解
    • 2.1 信息查询指令
    • 2.2 环境变量相关指令
    • 2.3 启动相关指令
    • 2.4 文件系统相关指令
    • 2.5 内存操作指令
    • 2.6 网络相关指令
    • 2.7 设备操作指令
    • 2.8 其他指令

1 U-Boot简介

U-Boot(Universal Bootloader)是一个开源的引导加载程序,主要用于嵌入式系统和嵌入式设备。它被设计成通用的,能够在多种处理器架构上运行,如ARM、MIPS、x86等。U-Boot的主要功能是加载并启动操作系统内核,最常见的是Linux内核。

以下是U-Boot引导Linux内核时所执行的主要步骤:

  1. 启动阶段(Boot ROM):
    • 当嵌入式设备上电或者复位时,处理器会从固定地址处的启动ROM(Boot ROM)中开始执行代码。
    • 启动ROM的主要任务是初始化系统的基本硬件,如时钟、内存控制器等,并加载U-Boot引导加载程序到RAM中。
  2. U-Boot初始化:
    • 一旦U-Boot加载到RAM中,它就开始执行。U-Boot首先进行硬件初始化,包括处理器、内存、外设等的配置。
    • U-Boot提供了一个命令行界面,允许用户进行配置和交互式操作。用户可以通过串口、网络或其他方式与U-Boot进行通信。
  3. 加载Linux内核:
    • U-Boot负责从存储介质(如Flash、SD卡、网络等)中加载Linux内核镜像到设备的内存中。这通常涉及到文件系统的读取和解析。
    • 用户可以在U-Boot命令行中手动输入加载内核的命令,也可以通过配置文件自动加载。
  4. 设备树加载:
    • 对于许多嵌入式系统,U-Boot还会加载设备树(Device Tree)。设备树是一种描述硬件设备和系统拓扑结构的数据结构,它允许Linux内核动态适应各种硬件配置。
  5. 传递控制权给Linux内核:
    • 一旦Linux内核被成功加载到内存中,U-Boot会设置一些必要的参数,如内核命令行参数、设备树的地址等。
    • U-Boot然后将控制权传递给Linux内核,使其开始执行。此时,Linux内核接管系统的控制权。

总的来说,U-Boot在嵌入式系统中的角色是引导加载程序,负责初始化硬件、加载操作系统内核、传递必要的参数,并最终将控制权交给内核。这使得U-Boot成为嵌入式系统中一个关键的组件,它的配置和功能对系统的启动和运行起着重要作用。

2 U-Boot命令行指令详解

在U-Boot运行后,会有一个倒计时,如果倒计时内我们按下键盘的任何按键,就可以进入U-Boot的命令行模式,如果不按下,则U-Boot会根据我们默认的启动参数来启动内核。这里我们就来介绍一下常用的U-Boot的命令行的指令。我们可以输入help查看支持的指令:
在这里插入图片描述
对于具体的指令,我们可以输入help 指令名来查看这个指令的用法,比如这里的base指令:
在这里插入图片描述
下面就具体来看一下这些指令的使用方法,对于不常用的指令,就不详细介绍或举例说明了。

2.1 信息查询指令

  • bdinfo:打印板级信息结构(Board Info structure),包括板级名称、序列号、CPU类型、时钟频率等。
    在这里插入图片描述

  • printenv:打印环境变量的值。
    在这里插入图片描述
    这里面有很多环境变量的值,比如串口的波特率,还有U-Boot上电后倒计时的值bootdelay。修改环境变量的指令参考下面的3.2 环境变量相关指令

  • version:打印U-Boot的版本信息、编译器和链接器的版本。
    在这里插入图片描述

2.2 环境变量相关指令

  • editenv:编辑环境变量。
    在这里插入图片描述
    以修改bootdelay参数为例,输入editenv bootdelay后,等于进入一个文本模式,这里显示了当前的初始值,我们只需要修改然后回车即可,这条指令修改环境变量很方便。

  • env:环境变量处理命令。
    在这里插入图片描述

  • saveenv:将环境变量保存到存储中。前面设置的变量默认是保存在RAM中,如果需要下次上电使用新设置的环境变量,需要保存到非易失存储中。

  • setenv:设置/新建/删除环境变量的值。

    • 我们可以调用set bootdelay 5修改环境变量的值,如果环境变量不存在,则会自动创建。如果参数为空,则可以删除环境变量,如set bootdelay
    • 有的U-Boot不支持识别参数中的空格,可能环境变量就设置为第一个空格前的值了,这个时候需要用单引号把参数括起来,如setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2'
  • setexpr:将环境变量设置为表达式的结果。

    • 举个例子,假设bootdelay为5,setexpr bootdelay1 $bootdelay + 2将设置bootdelay1为7。
  • showvar:打印本地hushshell变量。

2.3 启动相关指令

  • bootz:从内存中启动Linux zImage镜像。
    • 格式为:bootz [addr [initrd[:size]] [fdt]],其中addr为zImage地址,initrd为在系统引导过程中挂载的临时根文件系统,一般我们不使用,可以填-略过这个参数,fdt为设备树的地址。我们可以使用TFTPNFS等命令下载镜像到RAM后,使用bootz来启动内核:
tftp 80800000 zImage
tftp 83000000 imx6ull-alientek-emmc.dtb
bootz 80800000 – 83000000
  • bootm:从内存中启动uImage镜像。
    指令格式同bootzbootm [addr [initrd[:size]] [fdt]],如果不使用设备树,则直接bootm addr
  • boot:执行环境变量bootcmd中的启动命令。
    假设我们想每次都从TFTP下载镜像启动,我们就可以设置bootcmd,以后就输入boot就会执行bootcmd里的指令了。实际上前面所说的bootdelay倒计时结束后,默认也是执行bootcmd
    • 还有一个环境变量bootargs也与启动有关,它可以传参给内核,在后面的文章我们会介绍,这里先了解一下。
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-alientek-emmc.dtb; bootz
80800000 - 83000000'
saveenv
boot
  • bootd:和boot类似,执行bootcmd的命令,但它提供了额外的参数用来设置initrd,这里不介绍。
  • bootp:通过网络使用BOOTP/TFTP协议启动镜像。
  • bootvx:从内存中的ELF映像启动vxWorks操作系统。
  • bootelf:从内存中的ELF映像启动。ELF文件包含调试信息,我们仅在调试是使用这个ELF文件,最后能够运行的程序是bin程序,这个指令能从ELF中提取出原始的bin镜像。

2.4 文件系统相关指令

  • fatinfo:打印FAT文件系统的信息。
    • 格式为:fatinfo <interface> [<dev[:part]>]
      在这里插入图片描述
      上面查看了MMC(我这里MMC的dev为1)的第一个分区的文件系统信息
  • fatls:列出目录中的文件(默认为根目录)。
    我们在MMC的第一个分区里面的文件系统里存放了zimage和设备树。
    在这里插入图片描述
  • fstype:查看文件系统类型
    在这里插入图片描述
  • fatload:从文件系统中加载二进制文件到RAM。
    下面代码加载zImage到0x80000000处
fatload mmc 1:1 80000000 zImage
  • fatsize:确定文件的大小。
  • fatwrite:将文件写入DOS文件系统。
  • ls:列出目录中的文件(默认为根目录)。
  • load:从文件系统加载二进制文件。
  • save:将文件保存到文件系统。
  • ext2load:从Ext2文件系统加载二进制文件。
  • ext2ls:列出目录中的文件(默认为根目录)。
  • ext4load:从Ext4文件系统加载二进制文件。
  • ext4ls:列出目录中的文件(默认为根目录)。
  • ext4size:确定文件的大小。
  • ext4write:在根目录下创建文件。

2.5 内存操作指令

  • cmp:对比内存内容。

    • 类似C语言的memcmp,格式为:cmp [.b, .w, .l] addr1 addr2 count,将输出两个内存里的值是否相等。
  • cp:内存复制。

    • 类似C语言的memcpy,格式为:cp [.b, .w, .l] source target count
  • md(Memory Display):显示内存内容。

    • 格式为:md [.b, .w, .l] address [# of objects],其中b/w/l分别表示字节、半字和字
      在这里插入图片描述
      上图为显示0x80000000内存处的前0x10(16)个字节。
  • mm(memory modify):修改内存内容(自动增加地址)。

    • 格式为:mm [.b, .w, .l] address,输入后会进入交互模式,如果要退出保存,则输入空格回车即可。
      在这里插入图片描述
      上图就是每次修改一个字节,然后回车后修改下一个字节。
  • mtest:简单的RAM读写测试。

  • mw:写内存(填充)。

    • 格式为:mw [.b, .w, .l] address value [count]
      在这里插入图片描述
      上图填充0x80000000开始的8字节为0xab。
  • nm:修改内存内容(固定地址)。

    • 格式为:nm [.b, .w, .l] address
      在这里插入图片描述
      mm类似,但这里不递增,就是修改一个固定的内存的内容。这里没指定数据长度默认就是l,这里输入完后按回车退出不了,按输入q退出。

2.6 网络相关指令

在介绍网络相关的指令之前,先来介绍一下与网络有关的环境变量。在U-Boot使用以太网相关的指令时,比如初始化时,会从环境变量中取这些值进行配置。

环境变量描述
ipaddrIP地址,若不指定,可使用dhcp命令自动获取
ethaddrMAC地址
gatewayip网关
netmask子网
serverip服务器IP地址,一般为我们开发使用的Ubuntu的IP地址

如下图所示:
在这里插入图片描述

  • dhcp:通过DHCP/TFTP协议,使用网络启动镜像。
    • 如果只输入一个dhcp,就会通过路由器的DHCP服务分配一个IP地址给设备
    • 它还能从网络启动镜像,完整指令格式如下:dhcp [loadAddress] [[hostIPaddr:]bootfilename]
      在这里插入图片描述
      这里通过dhcp,路由器给设备分配了一个IP地址192.168.31.203
  • ping:向网络主机发送ICMP ECHO_REQUEST请求。
    在这里插入图片描述
    我们可以ping Ubuntu主机的IP看一下是否在线。

下面来介绍一下nfstftpboot两个指令,NFSTFTP的用处和环境搭建可以参考这篇文章:环境搭建之TFTP、NFS、SSH和FTP的安装和使用

  • nfs:通过网络文件系统下载镜像
    • 格式为:nfs [loadAddress] [[hostIPaddr:]bootfilename]
      现在假设我们的Ubuntu NFS服务器上有一个1.txt,文件内容为“123456\n”,它的十六进制如下:
      在这里插入图片描述
      执行nfs 80000000 192.168.31.120:/var/nfs/general/1.txt
      在这里插入图片描述
    • 如果确定两个板子ping通,但是板子使用nfs命令提示File lookup fail,大概率为版本原因,解决方法如下:
1.修改nfs-kernel-server文件
sudo vi /etc/default/nfs-kernel-server
更改RPCNFSDCOUNT="-V 2 8"和RPCMOUNTDOPTS="-V 2 --manage-gids"
2.重启NFS服务端
sudo /etc/init.d/nfs-kernel-server restart
  • tftpboot:通过TFTP协议传输镜像。
    • 格式为: tftpboot [loadAddress] [[hostIPaddr:]bootfilename],如果不指定服务端地址hostIPaddr,则会使用环境变量serverip
      假设Ubuntu TFTP目录中有一个1.txt,文件内容为“654321\n”,它的十六进制如下:
      在这里插入图片描述
      执行tftp 80000000 192.168.31.120:1.txt,这里不用指定tftp的文件目录,因为服务端的配置文件中有tftp的目录。
      在这里插入图片描述

2.7 设备操作指令

  • mmc:MMC子系统命令,可以用来读写EMMC、SD等与MMC协议兼容的设备,命令如下:
    在这里插入图片描述
    这里我的板子使用的EMMC,首先使用mmc list查看一下可用的MMC设备,然后使用mmc dev 1(后面还能跟一个分区参数,不写则默认第一个分区,假设要切换到分区2,则输入mmc dev 1 2)切换到EMMC,最后使用mmc part来查看一下MMC的分区。
    如果EMMC里有Linux的话,它是有3个分区的,第0个存放U-Boot,第1个存放Linux镜像和设备树,第2个存放根文件系统(下图中没有显示出0分区,但实际是存在的)。
    在这里插入图片描述
    下面我们从分区0中读取数据到RAM中,mmc read是按块读取的,这里MMC的一个块是512字节,下面我们从分区0的第0块开始读4个块到0x80000000处。
    在这里插入图片描述
    如果我们想烧录U-Boot,我们就可以使用mmc write来实现。首先使用前面所说的tftpbootnfs将Ubuntu中的U-Boot镜像拷贝到我们的RAM中,假设拷贝到了0x80000000处。然后我们要查看镜像的大小,假设镜像的大小为1800,则1800/512=3.51,即占据4个块的大小。注意命令的参数都是16进制。我们就可以调用下面命令对镜像进行烧录:
mmc dev 1 0
mmc write 80000000 2 4  # I.MX系列的启动头的前1024字节(前2个块)存放启动头信息,所以从第2块烧录
mmc partconf 1 1 0 0    # EMMC需要执行此指令来让分区1(参数1)可以被识别(参数2)
  • mmcinfo:显示MMC信息。
    在这里插入图片描述

  • i2c:I2C子系统命令,U-Boot支持与I2C设备进行通信
    在这里插入图片描述

  • sf:SPI Flash子系统命令。
    在这里插入图片描述

  • usb:USB子系统命令。
    在这里插入图片描述

  • usbboot:从USB设备启动。

    • 格式为:usbboot loadAddr dev:part

2.8 其他指令

  • ?:帮助命令的别名。
  • base:打印或设置地址偏移量。
  • bmp:操作BMP图像数据。
  • clocks:显示时钟信息。
  • coninfo:打印控制台设备和信息。
  • crc32:计算校验和。
  • dcache:启用或禁用数据缓存。
  • dm:驱动模型低级访问。
  • echo:将参数打印到控制台。
  • erase:擦除FLASH存储器。
  • exit:退出脚本。
  • false:什么也不做,返回失败。
  • flinfo:打印FLASH存储器信息。
  • fuse:Fuse子系统。
  • go:从指定地址开始执行应用程序。类似汇编LDR PC, =地址
  • gpio:查询和控制GPIO引脚。
  • help:打印命令描述/用法。
  • icache:启用或禁用指令缓存。
  • iminfo:打印应用程序映像的头信息。
  • imxtract:提取多重映像的一部分。
  • itest:根据整数比较返回真或假。
  • loadb:通过串行线加载二进制文件(Kermit模式)。
  • loads:通过串行线加载S-Record文件。
  • loadx:通过串行线加载二进制文件(Xmodem模式)。
  • loady:通过串行线加载二进制文件(Ymodem模式)。
  • loop:在地址范围上进行无限循环。
  • mdio:MDIO实用命令。
  • mii:MII实用命令。
  • nm:内存修改(常量地址)。
  • pmic:电源管理IC(PMIC)。
  • protect:启用或禁用FLASH写保护。
  • reset:执行CPU复位。
  • run:在环境变量中运行命令。
  • sleep:延迟一段时间。
  • source:从内存中运行脚本。
  • test:类似于/bin/sh的最小测试。
  • true:什么也不做,返回成功。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1370450.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Amazing OpenAI API:把非 OpenAI 模型都按 OpenAI API 调用

分享一个有趣的小工具&#xff0c;10MB 身材的小工具&#xff0c;能够将各种不同的模型 API 转换为开箱即用的 OpenAI API 格式。 让许多依赖 OpenAI API 的软件能够借助开发者能够接触到的&#xff0c;非 OpenAI 的 API 私有部署和使用起来。 写在前面 这个小工具软件写于两…

面试宝典进阶之redis缓存面试题

R1、【初级】Redis常用的数据类型有哪些&#xff1f; &#xff08;1&#xff09;String&#xff08;字符串&#xff09; &#xff08;2&#xff09;Hash&#xff08;哈希&#xff09; &#xff08;3&#xff09;List&#xff08;列表&#xff09; &#xff08;4&#xff09;Se…

zookeeper 与eureka区别

CAP定理 在分布式系统的发展中&#xff0c;影响最大的莫过于CAP定理了&#xff0c;是分布式系统发展的理论基石。 2000年&#xff0c;加州大学的计算机科学家 Eric Brewer提出了CAP猜想 2002 年&#xff0c;麻省理工学院的 Seth Gilbert 和 Nancy Lynch 从理论上证明了 CAP 猜…

深入理解 Hadoop (五)YARN核心工作机制浅析

概述 YARN 的核心设计理念是 服务化&#xff08;Service&#xff09; 和 事件驱动&#xff08;Event EventHandler&#xff09;。服务化 和 事件驱动 软件设计思想的引入&#xff0c;使得 YARN 具有低耦合、高内聚的特点&#xff0c;各个模块只需完成各自功能&#xff0c;而模…

静态关键字:static

static的作用 static是静态的意思&#xff0c;可以修饰成员变量和成员方法。 static修饰成员变量表示该成员变量只在内存中只存储一份&#xff0c;可以被共享访问、修改。 成员变量 分为2类 静态成员变量&#xff08;有static修饰&#xff0c;属于类&#xff0c;内存中加载…

【QML COOK】- 005-粒子系统(ParticleSystem)

1. 编辑main.qml import QtQuick import QtQuick.ParticlesWindow {width: 800height: 800visible: truetitle: qsTr("Hello World")color: "#000000"MouseArea {id: mouseAreaanchors.fill: parentonClicked: {hahaEmitter.pulse(2000)}}ParticleSystem {…

大众汽车宣布将ChatGPT,批量集成在多种汽车中!

1月9日&#xff0c;大众汽车在官网宣布&#xff0c;将ChatGPT批量集成到电动、内燃机汽车中。 大众表示&#xff0c;将ChatGPT与其IDA语音助手相结合&#xff0c;用户通过自然语言就能与ChatGPT进行互动&#xff0c;例如&#xff0c;帮我看看最近的三星米其林饭店在哪里&#…

上门洗衣洗鞋小程序多门店管理模式是怎么样的

做干洗店和洗鞋店的老板们很多都不止一个门店&#xff0c;多门店的管理模式下&#xff0c;去做一个上门洗衣洗鞋小程序&#xff0c;需要有哪些必要的功能才能让不同的门店管理起来不乱呢。首先需要先确定一下不同门店的管理都会面临哪些经营场景和需求。 第一&#xff0c;加盟店…

Android BUG 之 Error: Activity class {} does not exist

项目场景&#xff1a; 更换包名&#xff0c;运行报错 问题描述 原因分析&#xff1a; 在替换包名的时候要确认&#xff0c;配置文件跟build中的保持一致&#xff0c;在更换后还要将旧包的缓存数据清理掉 解决方案&#xff1a; 1 替换后删除 app 下的build 文件夹 2 Rebuild Pr…

openEuler22.0.3安装oracle11.2.0.4报错总结

openEuler是CentOS8系列魔改来的 1.xstart无法打开报错x11拒绝转义 yum install *x11* vi /etc/ssh/sshd_config X11Forwarding yes systemctl restart sshd 2.执行runinstaller报错,无论是直接无法打开界面报错: when installed in the jdk 1.2 Linux 还是打开界面报错: no o…

20、Kubernetes核心技术 - 基于Prometheus和Grafana搭建集群监控平台

目录 一、概述 二、监控平台架构图​编辑 三、部署 Prometheus 3.1、Prometheus简介 3.2、部署守护进程node-exporter 3.3、部署rbac 3.4、ConfigMap 3.5、Deployment 3.6、Service 3.7、验证Prometheus 四、部署Grafana 4.1、Deployment 4.2、Service 4.3、Ing…

每天刷两道题——第十一天

1.1滑动窗口最大值 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值 。 输入&#xff1a;nums [1,3,-1,-3,5,3,6,7], k 3 输出&…

Spark与Cassandra的集成与数据存储

Apache Spark和Apache Cassandra是大数据领域中两个重要的工具&#xff0c;用于数据处理和分布式数据存储。本文将深入探讨如何在Spark中集成Cassandra&#xff0c;并演示如何将Spark数据存储到Cassandra中。将提供丰富的示例代码&#xff0c;以帮助大家更好地理解这一集成过程…

pycharm的使用技巧

1.新建文件时,自动生成代码 settings->editor->file and code templates,选择python script ${NAME} 文件名 ${DATE} 日期 2.自动补齐自定义段落 settings->editor->live templates,在右侧点击+号,添加自定义的内容 完成之后,在下方勾选python 3.修改注释的…

服务器日常维护要素,应该如何做好维护

维护服务器的目的是为了让服务器的性能保持最佳状态&#xff0c;发现问题及时解决&#xff0c;没有问题也可以对相关的应用和配置进行调优。但也有很多用户疑问&#xff0c;服务器具体会有哪些方面需要维护的&#xff0c;今天就一起来看看吧。 服务器日常维护&#xff0c;主要包…

融云 CEO 董晗荣获 51CTO 「2023 年度科技影响力人物奖」

&#xff08;&#x1f446;点击获取《社交泛娱乐出海作战地图》&#xff09; 1 月 5 日&#xff0c;由知名 IT 技术媒体 51CTO 主办的第十八届“中国企业年终评选”正式揭晓榜单&#xff0c;融云 CEO 董晗荣获“2023 年度科技影响力人物奖”。关注【融云全球互联网通信云】了解…

java连接池、C3P0、Druid德鲁伊连接池技术

java线程池 连接池C3P0Druid 连接池 概念&#xff1a;其实就是一个容器(集合)&#xff0c;存放数据库连接的容器。当系统初始化好后&#xff0c;容器被创建&#xff0c;容器中会申请一些连接对象&#xff0c;当用户来访问数据库时&#xff0c;从容器中获取连接对象&#xff0c…

CAN位时序分解

标准位时序 CAN标准位时序描述如下表 段名称段的作用Tq数同步段 (SS: Synchronization Segment)用于多个连接在总线上的单元通过此段实现时序调整&#xff0c;同步进行接收和发送的工作。信号的跳变边沿最好出现在此段中。 若通讯节点检测到总线上信号的跳变沿被包含在 SS 段的…

电子学会C/C++编程等级考试2020年09月(一级)真题解析

C/C++编程(1~8级)全部真题・点这里 第1题:输出整数 输入四个整数,把输入的第三、第四个整数输出。 时间限制:3000 内存限制:65536 输入 只有一行,共四个整数,整数之间由一个空格分隔。整数是32位有符号整数。 输出 只有一行,二个整数,即输入的第三、第四个整数,以一…

阿里云 WindowsServer 使用之 配置 SQL Server 允许远程连接

阿里云 WindowsServer 使用之 配置 SQL Server 允许远程连接 第一步&#xff1a;安装 SQL Server 数据库 这是一个很详细的安装教程&#xff0c;可以参考一下 安装SQL Server详细教程 需要注意&#xff1a;安装实例时&#xff0c;建议在‘身份验证模式’直接选择“混合模式”…