The U-Boot Command Line
U-Boot is the boot loader on every Cargt board: it starts the processor’s memory, then loads the Linux kernel and device tree and starts Linux. Its command line is useful for trying a different device tree or root partition for one boot, checking the eMMC, and recovering a board whose Linux does not start. This page covers how to reach it and the commands that help most. The examples are from an i.MX 8M Plus 00377 on the 00365 carrier, running a wrynose image.
Getting to the Prompt
The U-Boot command line is on the debug serial console, the same UART that shows the Linux boot messages and login prompt. Connect a terminal program to it with these settings:
115200 baud, 8 data bits, no parity, 1 stop bit (115200 8N1)
No hardware or software flow control
From a Linux PC, for example:
picocom -b 115200 /dev/ttyUSB0 # exit with Ctrl+A, Ctrl+X
Power on or reboot the board. U-Boot prints the board and memory it found, then counts down; press any key before it reaches 0:
U-Boot 2024.04+gde16f4f1722+p0 (Sep 02 2024 - 10:44:35 +0000)
CPU: i.MX8MP[8] rev1.1 1600 MHz (running at 1200 MHz)
CPU: Industrial temperature grade (-40C to 105C) at 39C
Model: Cargt i.MX8MP 00377 OSM-L SOM on 00365 carrier board
DRAM: 4 GiB
...
MMC: FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
Loading Environment from MMC... OK
...
Net: eth0: ethernet@30be0000, eth1: ethernet@30bf0000 [PRIME]
Fastboot: Normal
Normal Boot
Hit any key to stop autoboot: 0
u-boot=>
The countdown is 2 seconds on i.MX boards and 1 second on STM32MP2 boards.
The prompt is u-boot=> on i.MX and STM32MP> on STM32MP2.
To get more time, lengthen the countdown from Linux before you reboot. The change is saved, so it applies to every boot until you set it back:
fw_setenv bootdelay 5 # 5 seconds
fw_setenv bootdelay # back to the built-in default
Type boot at the prompt to continue booting Linux as normal, or
reset to restart the board.
Finding Your Way Around
help list every command
help <command> usage of one command
version U-Boot version and build
bdinfo memory layout and board information
help lists each command with a one-line description:
u-boot=> help
? - alias for 'help'
base - print or set address offset
bdinfo - print Board Info structure
...
boot - boot default, i.e., run 'bootcmd'
...
cargt_eeprom- Cargt EEPROM inspect/repair utility
...
Commands can be shortened to any unambiguous prefix, for example
printenv to print. Press the up arrow for the previous command.
Numbers are hexadecimal: md 0x80000000 10 reads sixteen words.
version shows the U-Boot build. Software updates replace only the root
file system (see Software Updates), not U-Boot, so U-Boot stays the
version the board was flashed with.
The Environment
U-Boot’s settings are text variables in its environment, which is
saved on the eMMC. U-Boot Environment describes where it is stored,
the variables Cargt images use, and how to read and change it from Linux
with fw_printenv and fw_setenv. At the prompt:
printenv all variables
printenv fdtfile one variable
setenv bootdelay 5 set a variable (in memory only)
setenv bootdelay delete a variable
editenv fdtfile edit a variable in place
saveenv write the environment to the eMMC
env default -a go back to the built-in defaults (in memory)
run <variable> run the commands stored in a variable
setenv changes the copy in memory only. Until you run saveenv the
change lasts for the current boot, and is gone at the next reset. That
makes setenv followed by boot the safe way to try something, for
example a different device tree:
setenv fdtfile boot/imx8mp-cargt-00377-00365-glt1011280800is1.dtb
boot
If the new setting works, make it permanent with fw_setenv from Linux,
or with setenv and saveenv at the prompt.
Undoing a Bad Change
If you saved a setting that stops Linux from starting, for example an
fdtfile that does not exist, stop at the prompt and restore the
defaults:
env default -a
saveenv
boot
This also clears any settings you made on purpose, such as MAC addresses
written with fw_setenv (see Ethernet MAC Addresses) or a display device
tree. Note them first with printenv if you need them. To reset a single
variable instead:
env default fdtfile
saveenv
How i.MX Boards Boot
On the i.MX 95, the System Manager and OEI firmware run before U-Boot; see i.MX 95 Boot Firmware and System Manager. From U-Boot on, the i.MX SOMs boot the same way. These are the variables that control booting on the 00377:
u-boot=> printenv bootcmd mmcdev mmcpart mmcautodetect fdtfile boot_targets console
bootcmd=run distro_bootcmd;run bsp_bootcmd
mmcdev=2
mmcpart=2
mmcautodetect=yes
fdtfile=boot/imx8mp-cargt-00377-00365-hdmi.dtb
boot_targets=usb0 mmc1 mmc2
console=ttymxc3,115200
bootcmd runs two steps:
distro_bootcmdis U-Boot’s standard scan. It looks on the devices inboot_targetsfor anextlinux/extlinux.conf, aboot.scrscript or an EFI application, and boots the first one it finds. Cargt images contain none of these, so on a normal board the scan finds nothing and moves on. The devices and their order differ between SOMs; on the i.MX 93 00363 they aremmc0 mmc1 usb0.bsp_bootcmdloads the kernelboot/Imageand the device tree named byfdtfilefrom the ext4 root partitionmmcparton MMC devicemmcdev, and starts Linux withroot=/dev/mmcblk<mmcdev>p<mmcpart>.
Because the scan runs first, a microSD card or USB stick that carries a
boot.scr or an extlinux.conf takes over the boot. Remove it if a
board boots something unexpected.
During the scan U-Boot prints messages such as these; they are normal:
MMC: no card present
Unable to open OP-TEE session (err=-5)
mm_communicate failed!
Error: Cannot initialize UEFI sub-system, r = 3
Running BSP bootcmd ...
...
Failed to load 'boot.scr'
37603840 bytes read in 118 ms (303.9 MiB/s)
Booting from mmc ...
mmcautodetect=yes makes U-Boot set mmcdev to the device it booted
from at every boot: 2 on the 00377, whose eMMC is MMC device 2, and
0 on most other SOMs. Setting mmcdev yourself has no effect unless
you also set mmcautodetect to no.
To boot the other root partition once, for example to check the previous software version after an update (see Software Updates):
setenv mmcpart 1
boot
The kernel command line is built by mmcargs. To add kernel arguments
for one boot:
SOM |
How to add kernel arguments |
|---|---|
i.MX 95 00414 |
|
i.MX 8M Plus 00377 |
|
i.MX 91 and i.MX 93 |
No variable for this; edit |
Then run boot. In Linux, cat /proc/cmdline shows the command line
the kernel received.
How STM32MP2 Boards Boot
These examples are from an STM32MP257F 00395-01 on the 00365 carrier with the 5.5-inch display. The variables that control booting:
STM32MP> printenv bootcmd altbootcmd bootdelay bootcount bootlimit upgrade_available fdtfile boot_targets
bootcmd=echo 'Boot A';setenv altboot 0;run bootcmd_stm32mp
altbootcmd=echo 'Boot B';setenv altboot 1;run bootcmd_stm32mp
bootdelay=1
bootcount=1
bootlimit=3
upgrade_available=0
fdtfile=stm32mp257f-cargt-00395-01-00365-glt0557201280is1.dtb
boot_targets=mmc1
bootcmd_stm32mp sets boot_targets to the device the board booted
from, mmc1 (the eMMC), and runs distro_bootcmd. That scan looks at
the bootable partitions, the two boot file systems bootfs-a and
bootfs-b, and boots the extlinux.conf it finds. altboot=0
starts the scan at bootfs-a and altboot=1 at bootfs-b:
STM32MP> boot
Boot A
Boot over mmc1!
switch to partitions #0, OK
mmc1(part 0) is current device
Scanning mmc 1:6...
Found /mmc1_extlinux/extlinux.conf
Retrieving file: /mmc1_extlinux/extlinux.conf
...
1: OpenSTLinux
Retrieving file: /Image.gz
Retrieving file: /st-image-resize-initrd
append: root=/dev/mmcblk1p10 rootwait rw earlycon rauc.slot=A console=ttySTM0,115200
Retrieving file: /stm32mp257f-cargt-00395-01-00365-glt0557201280is1.dtb
...
Starting kernel ...
extlinux.conf names the kernel and the kernel command line
(append), and loads the device tree named by fdtfile. fdtfile
holds the file name alone, so the same one-boot test works:
setenv fdtfile stm32mp257f-cargt-00395-01-00365-glt1011280800is1.dtb
boot
On this board U-Boot also prints File not found /splash_landscape.bmp
and panel device error -19 while it reads extlinux.conf; they are
normal.
bootcmd boots the active slot. On slot A, as here, it prints
Boot A; RAUC rewrites bootcmd and altbootcmd when it switches
slots. While a newly installed slot is on trial (upgrade_available=1),
U-Boot counts its boots in bootcount, and after bootlimit (3)
failed boots it runs altbootcmd to go back to the other slot.
bootcount=1 above is the current boot; with upgrade_available=0
it is not saved, and Linux shows bootcount=0. RAUC A/B OTA Updates — STM32MP2 (00395-01-00365 / 00395-02-00365)
describes this in detail. Do not change these variables by hand unless you
are following that page.
Looking at Storage
mmc list the MMC devices: eMMC and microSD
mmc dev ${mmcdev} select the device U-Boot boots from
mmc info size and type of the selected device
mmc part its partition table
ls mmc ${mmcdev}:${mmcpart} /boot list a directory
load mmc ${mmcdev}:${mmcpart} ${loadaddr} /boot/Image read a file into memory
On the 00377:
u-boot=> mmc list
FSL_SDHC: 0
FSL_SDHC: 1
FSL_SDHC: 2 (eMMC)
u-boot=> mmc dev ${mmcdev}
switch to partitions #0, OK
mmc2(part 0) is current device
u-boot=> mmc part
Partition Map for MMC device 2 -- Partition Type: DOS
Part Start Sector Num Sectors UUID Type
1 16384 12582912 076c4a2a-01 83
2 12599296 12582912 076c4a2a-02 83
3 25182208 35889152 076c4a2a-03 83
u-boot=> ls mmc ${mmcdev}:${mmcpart} /boot
<DIR> 4096 .
<DIR> 4096 ..
<SYM> 39 Image
37603840 Image-6.18.20-2.0.0-g4a0a00cc7ffa-dirty
...
60925 imx8mp-cargt-00377-00365-glt0557201280is1.dtb
61026 imx8mp-cargt-00377-00365-glt1011280800is1.dtb
59631 imx8mp-cargt-00377-00365-hdmi.dtb
59064 imx8mp-cargt-00377-00365.dtb
Partitions 1 and 2 are the two root file systems and 3 is the data
partition (see Storage and Boot). ls and load work on ext4 and FAT
file systems. ls is the quickest way to check that a device tree you
are about to set in fdtfile exists.
On STM32MP2 boards the eMMC is MMC device 1 and has a GPT partition table
with named partitions, which mmc part lists with their GUIDs:
fip-a and fip-b (TF-A, OP-TEE and U-Boot), u-boot-env,
bootfs-a and bootfs-b, vendorfs-a and vendorfs-b,
rootfs-a and rootfs-b, and userfs. bootfs-a is partition
6, so ls mmc 1:6 / lists the kernel and device trees of slot A. In
Linux, the running slot’s bootfs is mounted at /boot.
Looking at Hardware
These commands only read. Use them to check that a device answers before Linux is involved:
i2c bus list the I²C buses
i2c dev 0 select bus 0
i2c probe list the addresses that answer on it
i2c md 0x50 0 0x10 read 16 bytes from address 0x50
gpio status the GPIOs U-Boot's drivers use
md ${loadaddr} 0x10 read memory
For example:
u-boot=> i2c dev 0
Setting bus to 0
u-boot=> i2c probe
Valid chip addresses: 25 32 50
U-Boot only knows the devices its own device tree describes, so gpio
status and i2c bus list fewer devices than Linux does.
On i.MX boards, cargt_eeprom read prints the production information
in the SOM’s EEPROM, including its part number:
u-boot=> cargt_eeprom read
Cargt EEPROM Production Information:
Part number: 012-00377-BE
Production date: 20260903
Serial number: 0x000xxxxx
EEPROM struct version: 0x2
DRAM rank: 1
DRAM size: 4096 MB
DRAM speed: 4000 MT/s
STM32MP2 U-Boot does not have cargt_eeprom.
U-Boot also has commands that write: mw, i2c mw, mmc write,
gpio set, cargt_eeprom setrank and others. They change hardware
directly and can leave a board that does not boot. Do not use the
fuse command at all: fuses are one-time programmable, and a wrong
value cannot be undone and can stop the processor from booting. Fuses are
only programmed as part of Secure Boot (AHAB) on i.MX 9.
Network and USB
U-Boot can use Ethernet for testing and for loading files from a TFTP server:
dhcp get an address
ping <address> check the connection
tftp ${loadaddr} <file> load a file from the TFTP server in serverip
dhcp tries the port marked [PRIME] in the boot messages first,
and moves on to the next port if that one has no link. After it gets an
address it also tries to load a file over TFTP, and reports an error when
no server is set. That error does not matter if you only wanted the
address. Here eth1 had no cable, and the address came over eth0:
To boot the kernel over TFTP and the root file system over NFS, see Booting over the Network (TFTP and NFS).
u-boot=> dhcp
ethernet@30bf0000 Waiting for PHY auto negotiation to complete......................................... TIMEOUT !
phy_startup() failed: -110FAILED: -110BOOTP broadcast 1
BOOTP broadcast 2
BOOTP broadcast 3
DHCP client bound to address <address> (1012 ms)
*** ERROR: `serverip' not set
Cannot autoload with TFTPGET
ums makes the eMMC appear on your PC as a USB drive, over the board’s
USB device port, so you can read or replace files without booting Linux:
ums 0 mmc ${mmcdev} share the eMMC; Ctrl+C to stop
Unmount the drive on the PC before you press Ctrl+C. ums was not run
for this page. Writing to a root
partition this way changes that slot outside the control of the software
update system.
To re-flash a board from U-Boot over USB, see NXP - Enter UUU mode using U-Boot Environment Variable Method for i.MX. On STM32MP2, STM32CubeProgrammer talks to U-Boot over USB in the same way; see Getting Started.