2020-11-20

TI U-Boot 使用指南

  1. Boot 流程
    在嵌入式平台上引导Linux内核并不像简单地将程序计数器指向内核位置并让处理器运行那么简单。在引导内核并在设备上运行之前必须运行的四个引导装载程序软件阶段。
    像AM335x这样的应用处理器是复杂的硬件,但是内部RAM有限(例如,128KB)。由于RAM有限,所以需要多个引导加载程序阶段。这些引导加载程序阶段系统地解锁设备的全部功能,以便内核可以使用设备的所有复杂性。
    有四个不同的引导加载程序阶段:
    2020-11-20_第1张图片
  1. ROM Code
    第一阶段引导加载程序位于设备的ROM中。ROM代码是设备启动或开机复位(POR)后自动运行的第一个代码块。ROM引导加载程序代码是硬编码到设备中,用户不能改变。正因为如此,理解ROM代码到底在做什么是很重要的。
    ROM代码有两个主要功能:
    •设备的配置和初始化主要外围设备,如堆栈设置,配置看门狗计时器(详见TRM)以及PLL和系统时钟配置
    •检查下一阶段引导加载程序(SPL)的引导源,并将实际的下一阶段引导加载程序代码加载到内存中并启动它,为下一阶段引导加载程序准备设备
    ROM代码将搜索第二阶段引导加载程序的引导设备列表是由设备SYSBOOT pin在启动时设置的电压级别配置的。这些引脚还设置了其他的引导参数(即预期的晶体频率,外部存储器的总线宽度)。有关SYSBOOT引脚和相关引导参数的更多信息,请参阅设备TRM。
  2. SPL or MLO
    第二阶段引导加载程序称为SPL(辅助程序加载程序),但有时也称为MLO (MMC卡加载程序)。SPL是U-Boot的第一个阶段,必须从一个引导源加载到内部RAM中。SPL具有非常有限的配置或用户交互,主要用于初始化外部DDR内存并为下一个引导加载程序阶段(U-Boot)设置引导进程。
    3)U-Boot
    U-Boot允许通过串行终端对内核引导环境进行强大的基于命令的控制。用户可以控制许多参数,比如引导参数和内核引导命令。此外,还可以配置U-Boot环境变量。这些环境变量存储在存储介质上的uEnv.txt文件中,或者直接存储在基于闪存的内存中(如果这样配置的话)。可以分别使用env print、env set和env save命令查看、修改和保存这些环境变量。U-Boot也是一个非常有用的工具,可以编程和操作各种外部存储设备,并且在定制电路板时也是一个有用的辅助工具。
    4)Linux Kernel
    zImage是一个压缩的内核映像,其中包含了描述内核的头信息。这个头包括目标体系结构、操作系统、内核大小、入口点等。内核映像的加载通常是通过使用存储在U-Boot环境中的脚本来执行的(所有这些都是从bootcmd ENV变量开始的,该变量在autoboot倒计时过期后执行,或者通过在U-Boot提示符处输入Boot命令来手动启动)。这还涉及到将一个特定于板的设备树blob(DTB)作为参数传递给U-Boot的bootz命令,该命令将提取并启动实际的内核。
  1. U-Boot 环境
    请注意,在许多板子上,我们在系统启动时修改了环境中的各种变量,比如board_name和ethaddr。当我们恢复默认值时,一些变量将变为未设置,这可能导致其他事情无法工作,例如依赖这些运行时设置变量的findfdt。
    恢复默认值
    可以将U-Boot环境变量集重置为默认值,如果需要,将它们保存到存储环境的位置(如果适用)。当u-boot版本从升级或降级更改时,还需要恢复默认设置。为此,请发出以下命令:
U-Boot # env default -f -a
U-Boot # saveenv

网络环境
使用USB以太网加密狗时,必须在环境中设置有效的MAC地址。然后发出以下命令:

U-Boot # setenv usbethaddr value:from:link:above

可以使用printenv命令查看是否已设置usbethaddr。
然后启动USB子系统:
U-Boot # usb start
U-Boot的默认行为是在用户发出DHCP命令时利用DHCP服务器传递给我们的所有信息。这将包括dhcp参数next-server,它指示通过TFTP从何处获取文件。但是,网络上的dhcp服务器可能会提供不正确的信息,因此您无法修改该服务器。在这种情况下,以下步骤可能会有所帮助:

U-Boot # setenv autoload no
U-Boot # dhcp
U-Boot # setenv serverip correct.server.ip
U-Boot # tftp

另一种选择是使用tftp命令的完整语法:

U-Boot # setenv autoload no
U-Boot # dhcp
U-Boot # tftp ${loadaddr} server.ip:fileName

2.1可用于映像下载的RAM
若要了解用于下载映像或其他用途的可用RAM数量,请使用bdinfo命令。

=> bdinfo
arch_number = 0x00000000
boot_params = 0x80000100
DRAM bank   = 0x00000000
-> start    = 0x80000000
-> size     = 0x7F000000
baudrate    = 115200 bps
TLB addr    = 0xFEFF0000
relocaddr   = 0xFEF30000
reloc off   = 0x7E730000
irq_sp      = 0xFCEF8880
sp start    = 0xFCEF8870
Early malloc usage: 890 / 2000

引导之后,U-Boot重新定位自己(以及它的各种保留RAM区域),并将自己放在可用RAM的末端(从上面bdinfo输出中的relocaddr开始)。只有堆栈位于该区域的前面。堆栈顶部的地址在sp开始在bdinfo输出,它向下增长。用户至少应该为堆栈保留大约1MB的空间,因此在上面的示例输出中,[0x80000000, 0xFCE00000]范围内的RAM可以安全地使用。
2.2 设备树
关于设备树的说明。现在所有支持的板都需要使用一个设备树来引导。为了便于在受支持的平台中实现这一点,可以使用U-Boot环境中的findfdt命令,该命令将fdtfile变量设置为要使用的设备树的名称,就像在内核源中找到的那样。在Keystone-2系列设备(K2H/K/E/L/G)中,它由name_fdt变量针对每个平台指定。设备树应该从与内核相同的媒体和相同的相对路径加载。
2.3 USB设备固件升级(DFU)
在使用USB设备固件升级(DFU)时,无论要写入的介质是什么,以及使用的板是什么,都要记住一些一般性的事情。首先,您需要在主机上安装dfu util程序的副本。如果您的发行版没有提供此包,则需要从源代码构建它。其次,下面的例子假设一个单板插在主机上。如果你有一个以上的设备插入,你需要使用dfu-util提供的选项来指定一个要使用的设备。最后,要通过DFU为给定的存储设备编程,请参阅您正在使用的存储设备的部分。
2.3.1 USB外设引导模式(支持SPL-DFU)
USB外设引导模式用于使用USB接口使用SPL-DFU功能引导。这里列出的步骤可以在支持USB外围设备引导模式的平台上使用。

  1. 在u-boot中启用SPL-DFU功能,并构建MLO/u-boot二进制文件。
  2. 加载MLO和u-boot.img使用主机PC中的dfu-util。
    3.u-boot启动后,使用u-boot中的DFU命令将主机PC(使用DFU UTIL工具)的二进制图像闪存到eMMC,或QSPI到新的/出厂板。
    这里提供的示例是dra7xx平台。
    使用默认“dra7xx\u evm\u defconfig”构建spl/u-boot-spl.bin,u-引导.img.
host$ make dra7xx_evm_defconfig
host$ make menuconfig

select SPL/DFU support
menuconfig->SPL/TPL--->
   ..
   [*] Support booting from RAM
   [*] Support USB Gadget drivers
   [ ]    Support USB Ethernet drivers
   [*]    Support DFU (Device Firmware Upgrade)
             DFU device selection (RAM device) -->
Unselect CONFIG_HUSH_PARSER
menuconfig--->Command Line interface
   [*] Support U-boot commands
   [ ]   Use hush shell
•	Build spl/u-boot-spl.bin and u-boot.img
host$ make

• 将SYSBOOT SW2开关设置为USB外设引导模式
SW2[7…0] = 00010000 (refer to TRM for various booting order)
• 通过USB电缆连接EVM高速端口(USB1端口)到PC (Ubuntu)。
• 从Ubuntu(或主机)PC,获取并构建usbboot应用程序。针对特定发行版的usbboot预构建的二进制文件可能已经在处理器SDK中可用了。下面是构建usbboot应用程序的步骤。
host$ git clone git://git.omapzoom.org/repo/omapboot.git
host$ cd omapboot
host$ checkout 609ac271d9f89b51c133fd829dc77e8af4e7b67e
host$ make -C host/tools
这就产生了名为usbboot- independent的主机端工具
要将spl/u-boot- spl .bin加载到EVM,请发出下面的命令并重置主板。

host$ sudo usbboot-stand-alone -S spl/u-boot-spl.bin
•	Load the u-boot.img to RAM.

• 加载u-boot.img到 RAM

host$ sudo dfu-util -l
Found DFU: [0451:d022] devnum=0, cfg=1, intf=0, alt=0, name="kernel"
Found DFU: [0451:d022] devnum=0, cfg=1, intf=0, alt=1, name="fdt"
Found DFU: [0451:d022] devnum=0, cfg=1, intf=0, alt=2, name="ramdisk"
host$ sudo dfu-util c 1 -i 0 -a 0 -D "u-boot.img" -R

• 现在EVM将引导到u-boot提示符。
2.4网络(有线或USB客户端)
本节介绍如何配置网络,并使用它加载文件,然后使用NFS上挂载的根文件系统引导Linux内核。此时,在受支持的硬件上执行这些操作不需要特殊的U-Boot构建。
2.4.1 从网络引导U-Boot
在某些情况下,由于支持ROM,我们支持通过网络加载SPL和U-Boot。在某些情况下,可能需要一个特殊的U-Boot构建。另外,需要DHCP服务器用要通过tftp获取的文件回复目标。为了方便这个操作,ROM填写了vendor-class-identifier DHCP字段,下面的表中列出了这些值。最后,需要使用spl/u-boot- splm .bin和启动u-boot.img文件。
如果使用ISC dhcpd,主机条目示例如下所示:

host am335x_evm {
  hardware ethernet de:ad:be:ee:ee:ef;
  # Check for PG1.0, typically CPSW
  if substring (option vendor-class-identifier, 0, 10) = "DM814x ROM" {
    filename "u-boot-spl.bin";
  # Check for PG2.0, CPSW or USB RNDIS
  } elsif substring (option vendor-class-identifier, 0, 10) = "AM335x ROM" {
    filename "u-boot-spl.bin";
  } elsif substring (option vendor-class-identifier, 0, 17) = "AM335x U-Boot SPL" {
    filename "u-boot.img";
  } else {
    filename "zImage-am335x-evm.bin";
  }
}

注意,在工厂类型设置中,可以在子网声明中进行子字符串测试,以设置子网的默认文件名值,并在主机条目中覆盖(如果需要)。
如果你已经从你的系统中删除了NetworkManager(这不是默认的大多数发行版),你需要配置你的/etc/network/interfaces文件:

allow-hotplug usb0
iface usb0 inet static
        address 192.168.1.1
        netmask 255.255.255.0
        post-up service isc-dhcp-server reload

如果使用NetworkManager,则需要创建两个文件。首先,作为root用户创建/etc/NetworkManager/system connections/AM335x USB RNDIS(并使用\来转义空间),其中包含以下内容:

[802-3-ethernet]
duplex=full
mac-address=AA:BB:CC:11:22:33

[connection]
id=AM335X USB RNDIS
uuid=INSERT THE CONTENTS OF 'uuidgen' HERE
type=802-3-ethernet

[ipv6]
method=ignore

[ipv4]
method=manual
addresses1=192.168.1.1;16;

作为root用户,并确保执行权限,创建/etc/NetworkManager/dispatcher.d/99am335x-dhcp-server

#!/bin/sh

IF=$1
STATUS=$2

if [ "$IF" = "usb0" ] && [ "$STATUS" = "up" ]; then
    service isc-dhcp-server reload
fi

2.4.2. 多接口
在某些电路板上,例如,当我们同时拥有有线接口和USB RNDIS gadget以太网时,可以将默认的U-Boot行为(在它知道的每个接口上循环)改为告诉U-Boot使用单个接口。例如,在开始时,你可能会看到这样的行:
Net: cpsw, usb_ether
因此,为了确保我们使用usb_ether,首先发出以下命令:

U-Boot # setenv ethact usb_ether

2.4.3. DHCP配置网络
要通过DHCP配置网络,请使用以下命令:

U-Boot # setenv autoload no
U-Boot # dhcp

并确保DHCP服务器配置为为所连接的网络提供地址。
2.4.4. 手动配置网络
要手动配置网络,ipaddr、serverip、gatewayip和netmask:

U-Boot # setenv ipaddr 192.168.1.2
U-Boot # setenv serverip 192.168.1.1
U-Boot # setenv gatewayip 192.168.1.1
U-Boot # setenv netmask 255.255.255.0

2.4.5 从网络引导Linux
在每个支持联网的板的默认环境中,有一个引导命令,在AM EVMs中称为netboot,在KS2 EVMs中称为boot=net,它将自动加载内核并引导。要获得每个命令的确切细节,请在netboot变量上使用printenv,然后依次在命令的其他子节上使用printenv。AM57x/DRA7x中最重要的变量是rootpath和nfsopts, K2H/K/E/L/G中的tftp_root和nfs_root。
在AM65x GP和IDK板上,Linux内核也可以通过PRU-ICSSG以太网端口引导。在发行版u-boot映像中,只有ICSSG0、ICSSG1和ICSSG2的第一个端口(MII端口0)是启用的。要使用第二个端口(MII端口1),用户需要编辑DTS文件以启用第二个端口而不是第一个端口,并使用更新后的DTS文件重新构建u-boot映像。第一个端口在IDK应用程序板上标记为Eth0 (ICSSG2)、Eth0 (ICSSG0)和Eth2 (ICSSG1)。用户需要使用如下所示的env脚本在ICSSG上加载和运行pru/rtu固件,然后通过ICSSG端口进行网络操作,如dhcp、tftp。为此,固件从rootfs/lib/firmware/ti-pruss/文件夹加载。有关在Uboot中使用rproc/RemoteProc的更多信息,请参见这里的部分。下面显示了用于ICSSG0、ICSSG1和ICSSG2的AM65x EVM/IDK示例U-Boot env脚本。用户需要将serverip和bootdir env变量定制为设置中使用的tftp服务器的变量。
请注意
目前,ICSSG端口只支持100Mbps和1Gbps全双工(FD)链路。通过PRUETH以太网接口使用NFS rootfs引导Linux内核还没有经过验证。

setenv start_icssg0 'rproc start 2; rproc start 3'
setenv stop_icssg0 'rproc stop 2; rproc stop 3'
setenv firmware_dir '/lib/firmware/ti-pruss'
setenv get_fdt_net 'run start_icssg0; tftp ${fdtaddr} ${serverip}:${bootdir}/${name_fdt}; run stop_icssg0'
setenv get_kern_net 'run start_icssg0; tftp ${loadaddr} ${serverip}:${bootdir}/${name_kern}; run stop_icssg0'
setenv get_overlay_net 'fdt address ${fdtaddr};fdt resize 0x0fffff;for overlay in $overlay_files;do; run start_icssg0; \
        tftp ${overlayaddr} ${bootdir}/${overlay};fdt apply ${overlayaddr}; run stop_icssg0; done;'
setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr} ${firmware_dir}/${firmware_file}'
setenv serverip 158.218.113.14
setenv bootdir 06.02.00.58-am6
setenv name_fdt k3-am654-base-board.dtb
setenv name_kern Image-am65xx-evm.bin
setenv overlay_files 'k3-am654-idk.dtbo k3-am654-pcie-usb2.dtbo'
setenv init_icssg0 'setenv ethact pruss0_eth; setenv autoload no; rproc init; setenv loadaddr 0x80000000; \
        setenv firmware_file 'am65x-pru0-prueth-fw.elf'; run get_firmware_mmc;  rproc load 2 0x80000000 13040; rproc start 2; \
        setenv loadaddr 0x89000000; setenv firmware_file am65x-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 3 0x89000000 5676; \
        rproc start 3; dhcp; run stop_icssg0;'
setenv bootcmd 'run init_mmc; run init_icssg0; run get_kern_net; run get_fdt_net ; run get_overlay_net ; run run_kern'
saveenv
boot
ICSSG1 port 0
setenv start_icssg1 'rproc start 6; rproc start 7'
setenv stop_icssg1 'rproc stop 6; rproc stop 7'
setenv firmware_dir '/lib/firmware/ti-pruss'
setenv get_fdt_net 'run start_icssg1; tftp ${fdtaddr} ${serverip}:${bootdir}/${name_fdt}; run stop_icssg1'
setenv get_kern_net 'run start_icssg1; tftp ${loadaddr} ${serverip}:${bootdir}/${name_kern}; run stop_icssg1'
setenv get_overlay_net 'fdt address ${fdtaddr};fdt resize 0x0fffff;for overlay in $overlay_files;do; run start_icssg1; \
      tftp ${overlayaddr} ${bootdir}/${overlay};fdt apply ${overlayaddr}; run stop_icssg1; done;'
setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr} ${firmware_dir}/${firmware_file}'
setenv serverip 158.218.113.14
setenv bootdir 06.02.00.58-am6
setenv name_fdt k3-am654-base-board.dtb
setenv name_kern Image-am65xx-evm.bin
setenv overlay_files 'k3-am654-idk.dtbo k3-am654-pcie-usb2.dtbo'
setenv init_icssg1 'setenv ethact pruss1_eth; setenv autoload no; rproc init; setenv loadaddr 0x80000000; \
      setenv firmware_file 'am65x-pru0-prueth-fw.elf'; run get_firmware_mmc;  rproc load 6 0x80000000 13040; rproc start 6; \
      setenv loadaddr 0x89000000; setenv firmware_file am65x-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 7 0x89000000 5676; \
      rproc start 7; dhcp; run stop_icssg1;'
setenv bootcmd 'run init_mmc; run init_icssg1; run get_kern_net; run get_fdt_net ; run get_overlay_net ; run run_kern'
saveenv
boot
ICSSG2 port 0
setenv start_icssg2 'rproc start 10; rproc start 11'
setenv stop_icssg2 'rproc stop 10; rproc stop 11'
setenv firmware_dir '/lib/firmware/ti-pruss'
setenv get_fdt_net 'run start_icssg2; tftp ${fdtaddr} ${serverip}:${bootdir}/${name_fdt}; run stop_icssg2'
setenv get_kern_net 'run start_icssg2; tftp ${loadaddr} ${serverip}:${bootdir}/${name_kern}; run stop_icssg2'
setenv get_overlay_net 'fdt address ${fdtaddr};fdt resize 0x0fffff;for overlay in $overlay_files;do; run start_icssg2; \
     tftp ${overlayaddr} ${bootdir}/${overlay};fdt apply ${overlayaddr}; run stop_icssg2; done;'
setenv get_firmware_mmc 'load mmc ${bootpart} ${loadaddr} ${firmware_dir}/${firmware_file}'
setenv serverip 158.218.113.14
setenv bootdir 06.02.00.58-am6
setenv name_fdt k3-am654-base-board.dtb
setenv name_kern Image-am65xx-evm.bin
setenv overlay_files 'k3-am654-idk.dtbo k3-am654-pcie-usb2.dtbo'
setenv init_icssg2 'setenv ethact pruss2_eth; setenv autoload no; rproc init; setenv loadaddr 0x80000000; \
     setenv firmware_file 'am65x-pru0-prueth-fw.elf'; run get_firmware_mmc;  rproc load 10 0x80000000 13040; rproc start 10; \
     setenv loadaddr 0x89000000; setenv firmware_file am65x-rtu0-prueth-fw.elf; run get_firmware_mmc; rproc load 11 0x89000000 5676; \
     rproc start 11; dhcp; run stop_icssg2;'
setenv bootcmd 'run init_mmc; run init_icssg2; run get_kern_net; run get_fdt_net ; run get_overlay_net ; run run_kern'
saveenv
boot

2.5 NAND
本节介绍如何将文件写入NAND设备,并使用NAND上的根文件系统加载和引导Linux内核。
2.5.1擦除、读写NAND分区
清单NAND闪存分区
下面的命令用于查看U-boot中启用的mtd设备列表

mtdparts
Example output on DRA71x EVM:
device nand0 <nand.0>, # parts = 10
 #: name                size            offset          mask_flags
 0: NAND.SPL            0x00020000      0x00000000      0
 1: NAND.SPL.backup1    0x00020000      0x00020000      0
 2: NAND.SPL.backup2    0x00020000      0x00040000      0
 3: NAND.SPL.backup3    0x00020000      0x00060000      0
 4: NAND.u-boot-spl-os  0x00040000      0x00080000      0
 5: NAND.u-boot         0x00100000      0x000c0000      0
 6: NAND.u-boot-env     0x00020000      0x001c0000      0
 7: NAND.u-boot-env.backup10x00020000   0x001e0000      0
 8: NAND.kernel         0x00800000      0x00200000      0
 9: NAND.file-system    0x0f600000      0x00a00000      0

注意:在后面的部分中,符号应该替换为执行mtdparts命令时看到的分区名。
擦除分区

nand erase.part <partition name>

写入分区
当写入NAND分区时,要写入的文件必须事先复制到内存中。

nand write <ddr address> <partition name> <file size>

符号表示文件被读入ddr内存的内存位置。符号表示要写入NAND分区的文件字节数(十六进制)。注意:在将文件读入DDR时,U-boot默认将环境变量“filesize”的值设置为通过上一个read/load命令读取的字节数(十六进制)。

下面的一个例子展示了将内核(zImage)写入NAND的内核分区的过程。要写入的zImage是从SD卡的rootfs(第二个)分区加载的。将zImage从MMC加载到DDR内存

U-Boot # mmc dev 0;
U-Boot # setenv devnum 0
U-Boot # setenv devtype mmc
U-Boot # mmc rescan
U-Boot # load ${devtype} 1:2 ${loadaddr} /boot/zImage

现在zImage被加载到内存中,将其写入NAND分区

U-Boot # nand erase.part NAND.kernel
U-Boot # nand write ${loadaddr} NAND.kernel ${filesize}

从分区中读
nand read
符号应替换为要将NAND分区内容复制到ddr中的位置。符号包含要从中读取的NAND分区名称
2.5.2通过DFU写入到NAND
目前在支持使用DFU的板子中,默认的构建支持写入NAND,所以不需要自定义构建。要查看要写入的可用位置列表(在DFU术语中是altsettings),请使用mtdparts命令列出已知的MTD分区和printenv dfu_alt_settings,以查看如何映射它们并将其暴露给dfu-util。

U-Boot # mtdparts

device nand0 <nand0>, # parts = 8
 #: name                size            offset          mask_flags
 0: NAND.SPL            0x00020000      0x00000000      0
 1: NAND.SPL.backup1    0x00020000      0x00020000      0
 2: NAND.SPL.backup2    0x00020000      0x00040000      0
 3: NAND.SPL.backup3    0x00020000      0x00060000      0
 4: NAND.u-boot         0x001e0000      0x00080000      0
 5: NAND.u-boot-env     0x00020000      0x00260000      0
 6: NAND.kernel         0x00500000      0x00280000      0
 7: NAND.file-system    0x0f880000      0x00780000      0

active partition: nand0,0 - (SPL) 0x00080000 @ 0x00000000
U-Boot # printenv dfu_alt_info_nand
dfu_alt_info=NAND.SPL part 0 1;NAND.SPL.backup1 part 0 2;NAND.SPL.backup2 part 0 3;NAND.SPL.backup3 part 0 4;NAND.u-boot part 0 5;NAND.kernel part 0 7;NAND.file-system part 0 8

这意味着您可以告诉dfu util将任何内容写入:
• NAND.SPL
• NAND.SPL.backup1
• NAND.SPL.backup2
• NAND.SPL.backup3
• NAND.u-boot
• NAND.kernel
• NAND.file-system
在写入之前,您必须至少擦去要写入的区域。然后在第一个NAND设备上的目标上启动DFU:

U-Boot # nand erase.chip
U-Boot # setenv dfu_alt_info ${dfu_alt_info_nand}
U-Boot # dfu 0 nand 0

然后在主机上将MLO写入第一个SPL分区:
$ sudo dfu-util -D MLO -a NAND.SPL
2.5.3 NAND引导
如果想从NAND加载并运行U-Boot,第一步是确保在正确的分区中加载了适当的U-Boot文件。对于AM335x、AM437x、DRA7x设备,这意味着将文件MLO写入NAND的SPL分区。对于OMAP-L138设备,将.ais映像写入NAND的分区。对于所有设备,这都需要写入u-boot.img到NAND的U-Boot分区。
请注意
OMAP-L138的NAND分区与其他设备不同,请使用以下命令对NAND进行编程

=> setenv ipaddr <EVM_IPADDR>
=> setenv serverip <TFTP_SERVER_IPADDR>
=> tftp ${loadaddr} ${serverip}:u-boot-omapl138-lcdk.ais
=> print filesize
=> nand erase 0x20000 <hex_len>
=> nand write ${loadaddr} 0x20000 <hex_len>
* hex_len is next sector boundary of the filesize. The sector size is 0x10000.
set dip switch to NAND boot and power cycle the EVM

一旦文件已写入NAND,则应关闭主板电源。下一个evm的引导开关需要配置为NAND引导。要了解适当的启动开关设置,请参阅evm的硬件设置指南。
2.5.4从NAND引导内核和文件系统
如果用户想使用NAND作为他们的主存储,那么NAND闪存必须为所有引导内核所需的关键软件拥有单独的分区。这至少包括内核、dtb和文件系统。一些soc需要额外的文件和固件,这些文件和固件也需要存储在不同的NAND分区中。
与从任何接口引导内核类似,用户必须确保引导所需的所有文件都加载到DDR内存中。唯一的例外是将由内核通过bootargs参数加载的文件系统。Bootargs包含传递给内核的信息,包括在哪里和如何挂载文件系统。
下面包含DRA7x evm用于使用ubifs文件系统的示例启动文件

setenv bootargs console=${console} ${optargs} root=ubi0:rootfs rw ubi.mtd=NAND.file-system,2048 rootfstype=ubifs rootwait=1
In the above example bootargs, “rootfs” stands for the value specified by in the “vol_name” parameter defined in the ubinize.cfg file. In ubi.mtd “NAND.file-system” and “2048” represents the name of the partition that contains the ubifs and page size. Rootfstype simply tells the kernel what type of file system to use.

在上面的示例bootargs中,“rootfs”代表ubinalize .cfg文件中定义的参数“vol_name”中指定的值。无论在哪里。mtd”NAND闪存。文件系统”和“2048”表示包含ubifs和页面大小的分区的名称。Rootfstype只是告诉内核要使用哪种类型的文件系统。

在默认情况下,evms的正确加载、设置引导程序和引导内核是通过在U-boot中运行“run nandboot”来处理的。关于创建UBIFS的信息可以在这里找到
2.6 SD, eMMC or USB Storage
使用SD卡、eMMC闪存和USB大容量存储设备(硬盘、闪存驱动器、读卡器等)的命令都非常相似。最大的区别是,在某些硬件上,我们可能无法从存储设备运行U-Boot,因为它不受支持。但是,在U-Boot运行之后,这些文件系统都可以用于内核和根文件系统。
2.6.1从U-Boot分区eMMC
eMMC设备通常不附带任何分区表。我们利用U-Boot中的GPT支持将GPT分区表写入eMMC。在这种情况下,我们需要使用主机上的uuidgen程序来创建用于磁盘和每个分区的UUIDs。

$ uuidgen
...first uuid...
$ uuidgen
...second uuid...
U-Boot # printenv partitions
uuid_disk=${uuid_gpt_disk};name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}
U-Boot # setenv uuid_gpt_disk ...first uuid...
U-Boot # setenv uuid_gpt_rootfs ...second uuid...
U-Boot # gpt write mmc 1 ${partitions}

需要重置分区表才能使其可见
2.6.2从主机PC更新SD卡
本节假设您已经按照处理器SDK Linux上的说明创建了SD卡脚本,或者手工制作了兼容的布局。在这种情况下,您需要复制所有引导映像(MLO和u-boot.img对于32位平台,tiboot3.bin,sysfw.itb, tispl.bin,u-boot.img对于基于K3的平台)文件到引导分区。此时,该卡现在可以在SD卡插槽中启动。我们默认在rootfs分区上使用/boot/${bootfile}和从/boot加载的设备树文件,名称与内核中的名称相同。
但是,如果您使用基于OMAP-L138的板(如LCDK),则需要编写生成的u-boot.ais使用dd命令将映像发送到SD卡。

$ sudo dd if=u-boot.ais of=/dev/sd<N> seek=117 bs=512 conv=fsync

2.6.3使用DFU更新SD卡或eMMC
要查看要写入的可用位置列表(在DFU术语中是altsettings),请使用mmc part命令列出mmc设备上的分区,并使用printenv dfu_alt_settings_mmc或dfu_alt_settings_emmc查看如何映射它们并将其暴露给dfu-util。

U-Boot# mmc part

Partition Map for MMC device 0  --   Partition Type: DOS

Partition     Start Sector     Num Sectors     Type
    1                   63          144522       c Boot
    2               160650         1847475      83
    3              2024190         1815345      83
U-Boot# printenv dfu_alt_info_mmc
dfu_alt_info=boot part 0 1;rootfs part 0 2;MLO fat 0 1;u-boot.img fat 0 1;uEnv.txt fat 0 1"

这意味着您可以告诉dfu util将任何内容写入:
• boot
• rootfs
• MLO
• u-boot.img
• uEnv.txt
MLO, u-boot。img和uEnv.txt文件将被写入FAT文件系统。
在第一个MMC设备上的目标设备上启动DFU:

U-Boot # setenv dfu_alt_info ${dfu_alt_info_mmc}
U-Boot # dfu 0 mmc 0

在像AM57x GP EVM或BeagleBoard x15这样的板上,第二个USB实例被用作USB客户端,dfu命令变成:

U-Boot # dfu 1 mmc 0

然后在主机PC上写MLO到一个现有的引导分区:

$ sudo dfu-util -D MLO -a MLO

在主机PC上覆盖当前引导分区内容,在主机FAT文件系统映像上创建一个新分区:

$ sudo dfu-util -D fat.img -a boot

2.6.4用原始写操作更新SD卡或eMMC
在某些情况下,最好编写MLO和u-boot。img作为到MMC设备的原始映像,而不是放在文件系统中。例如,eMMC需要这样做。在这种情况下,下面将介绍如何对这些文件进行编程,而不覆盖设备上的分区表。我们假设文件存在于SD卡上。此外,您可能希望将文件系统映像写入设备,因此本文还提供了一个示例。

U-Boot # mmc dev 0
U-Boot # mmc rescan
U-Boot # mmc dev 1
U-Boot # fatload mmc 0 ${loadaddr} MLO
U-Boot # mmc write ${loadaddr} 0x100 0x100
U-Boot # mmc write ${loadaddr} 0x200 0x100
U-Boot # fatload mmc 0 ${loadaddr} u-boot.img
U-Boot # mmc write ${loadaddr} 0x300 0x400
U-Boot # fatload mmc 0 ${loadaddr} rootfs.ext4
U-Boot # mmc write ${loadaddr} 0x1000 ...rootfs.ext4 size in bytes divided by 512, in hex...

2.6.5从SD卡或eMMC引导Linux
在支持SD/MMC的每个主板的默认环境中,都有一个名为mmcboot的引导命令,它将正确设置引导参数并启动内核。但是,在这种情况下,必须首先运行loaduimagefat或loaduimage,以便首先将内核加载到内存中。要获得每个命令的详细信息,请在mmcboot、loaduimagefat和loaduimage变量上使用printenv,然后依次使用printenv命令的其他子节。这里最重要的变量是mmcroot和mmcrootfstype。
2.6.6从eMMC引导分区引导MLO和u-boot
name: booting-mlo-and-u-boot-from-emmc-boot-partition
dra7xx和am57xx处理器支持从eMMC引导分区引导。以下命令从网络加载引导映像并将它们写入boot0分区。

U-boot # setenv autoload no
U-boot # dhcp
U-boot # mmc dev 1 1
U-boot # tftp ${loadaddr} dra7xx/MLO
U-boot # mmc write ${loadaddr} 0x0 0x300
U-boot # tftp ${loadaddr} dra7xx/u-boot.img
U-boot # mmc write ${loadaddr} 0x300 0x400

我们还需要使用bootbus和partconf命令配置eMMC。bootbus命令将eMMC设置为双数据率模式,总线宽度为8,以匹配引导ROM支持的总线配置。partconf命令允许在引导操作期间访问引导分区。注意,这些配置仅限于引导操作,一旦引导操作完成,eMMC可以设置为最高速度模式。所有这些都是非易失性配置,需要在每个eMMC/板上完成一次。

U-boot # mmc bootbus 1 2 0 2
U-boot # mmc partconf 1 1 1 0
U-boot # mmc rst-function 1 1

2.6.7引导tiboot3.bin, tispl.bin和u-boot.img来自eMMC引导分区
基于K3的处理器支持从eMMC引导分区引导。可以使用以下命令下载tiboot3.bin, tispl.bin和u-boot.img从SD卡,并将它们分别写入eMMC boot0分区。

=> mmc dev 0 1
=> fatload mmc 1 ${loadaddr} tiboot3.bin
=> mmc write ${loadaddr} 0x0 0x400
=> fatload mmc 1 ${loadaddr} tispl.bin
=> mmc write ${loadaddr} 0x400 0x1000
=> fatload mmc 1 ${loadaddr} u-boot.img
=> mmc write ${loadaddr} 0x1400 0x2000
=> fatload mmc 1 ${loadaddr} sysfw.itb
=> mmc write ${loadaddr} 0x3600 0x800

要让ROM访问引导分区,必须在第一次使用以下命令:

=> mmc partconf 0 1 1 1
=> mmc bootbus 0 2 0 0

2.6.8从USB存储引导Linux
名称:booting-linux-from-usb-storage
要从AMx/DRA7x EVMs上的USB卡而不是SD/MMC卡加载Linux内核和rootfs,如果我们假设USB设备的分区方式与SD/MMC卡相同,我们可以使用mmcboot命令进行引导。为此,请执行以下步骤:

U-Boot # usb start
U-Boot # setenv mmcroot /dev/sda2 ro
U-Boot # run mmcargs
U-Boot # run bootcmd_usb

在K2H/K/E/L EVMs上,内核中的USB驱动程序需要是内置的(默认模块)。配置变化如下:

CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_PCI=y
CONFIG_USB_XHCI_PLATFORM=y
CONFIG_USB_STORAGE=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_HOST=y
CONFIG_USB_DWC3_KEYSTONE=y
CONFIG_EXTCON=y
CONFIG_EXTCON_USB_GPIO=y
CONFIG_SCSI_MOD=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y

USB引导分区为FAT32格式,rootfs分区为EXT4格式。引导分区必须包含以下映像:

keystone-<platform>-evm.dtb
skern-<platform>.bin
k2-fw-initrd.cpio.gz
zImage

where <platform>=k2hk, k2e, k2l

rootfs分区包含ProcSDK发布包中的文件系统。

# mkdir /mnt/temp
# mount -t ext4 /dev/sdb2 /mnt/temp
# cd /mnt/temp
# tar xvf /filesyste/tisdk-server-rootfs-image-k2hk-evm.tar.xz
# cd /mnt
# umount temp

设置以下u-boot环境变量:

setenv args_all 'setenv bootargs console=ttyS0,115200n8 rootwait'
setenv args_usb 'setenv bootargs ${bootargs} rootdelay=3 rootfstype=ext4 root=/dev/sda2 rw'
setenv get_fdt_usb 'fatload usb 0:1 ${fdtaddr} ${name_fdt}'
setenv get_kern_usb 'fatload usb 0:1 ${loadaddr} ${name_kern}'
setenv get_mon_usb 'fatload usb 0:1 ${addr_mon} ${name_mon}'
setenv init_fw_rd_usb 'fatload usb 0:1 ${rdaddr} ${name_fw_rd}; setenv filesize ; run set_rd_spec'
setenv init_usb 'usb start; run args_all args_usb'
setenv boot usb
saveenv
boot

注意::必须至少是k2-fw-initrd.cpio.gz文件大小的十六进制大小。
2.6.9。从SD/eMMC从SPL启动(单阶段或Falcon模式)
在这种引导模式下,SPL(第一阶段引导加载程序)直接引导Linux内核。可选地,为了进入U-Boot,在按下串行终端上的“c”键时重置主板。当在U-Boot构建中启用falcon模式(通常是默认启用的)时,MLO检查在定义的偏移位置是否存在有效的uImage。如果uImage存在,它将直接引导。如果没有找到有效的uImage, MLO将返回检查uImage是否存在于FAT分区中。如果失败,它会回到u-boot.img的引导。
falcon引导使用uImage。要构建内核uImage,您需要在$PATH中保留U-Boot工具mkimage

# make uImage modules dtbs LOADADDR=80008000

如果内核没有使用CONFIG_CMDLINE来设置正确的引导程序,那么使用fdtput主机实用程序在DTB文件中chosen的节点中添加所需的引导程序。例如,对于DRA74x EVM:

# fdtput -v -t s arch/arm/boot/dts/dra7-evm.dtb "/chosen" bootargs "console=ttyO0,115200n8 root="

MLO,u-boot.img(可选)、DTB、uImage都存储在同一介质上,无论是SD还是eMMC。有两种方法可以将二进制文件存储在SD(resp)中。eMMC):
*raw:二进制文件存储在介质中的固定偏移量
*fat:二进制文件存储在fat分区中
要将二进制文件闪存到SD或eMMC,可以使用DFU。对于SD引导,从u-boot提示符

=> env default -a; setenv dfu_alt_info ${dfu_alt_info_mmc}; dfu 0 mmc 0

对于eMMC引导,从u-boot提示符

=> env default -a; setenv dfu_alt_info ${dfu_alt_info_emmc}; dfu 0 mmc 1

注:在AM57x GP EVM或BeagleBoard x15这样的板上,第二个USB实例用作USB客户端,请将“dfu 0 mmc X”替换为“dfu 1 mmc X”
在主机端:FAT中的二进制文件:

$ sudo dfu-util -D MLO -a MLO
$ sudo dfu-util -D u-boot.img -a u-boot.img
$ sudo dfu-util -D dra7-evm.dtb -a spl-os-args
$ sudo dfu-util -D uImage -a spl-os-image
raw binaries:
$ sudo dfu-util -D MLO -a MLO.raw
$ sudo dfu-util -D u-boot.img -a u-boot.img.raw
$ sudo dfu-util -D dra7-evm.dtb -a spl-os-args.raw
$ sudo dfu-util -D uImage -a spl-os-image.raw

如果二进制文件是fat分区中的文件,如果它们与默认值(“uImage”和“args”)不同,则需要指定它们的名称。注意,DFU使用名称“splm -os-image”和“splm -os-args”,因此这一步在DFU中是必需的。从u-boot提示

=> setenv falcon_image_file spl-os-image
=> setenv falcon_args_file spl-os-args
=> saveenv

将环境变量“boot_os”设置为1。从u-boot提示

=> setenv boot_os 1
=> saveenv

设置主板从SD启动(或分别从eMMC启动)并重置EVM。SPL直接从SD(或eMMC)引导内核映像。
2.7 SPI
本节介绍如何将文件写入SPI设备,并使用SPI上的根文件系统加载和引导Linux内核。此时,在受支持的硬件上执行这些操作不需要特殊的U-Boot构建。但是,下表列出了在环境中也使用SPI flash而不是默认的构建,在AM57x和DRA7x EVMs中通常是NAND,但在Keystone-2 EVMs中是only NOR。最后,为了简单起见,我们假设文件是从SD卡加载的。使用网络接口(如果适用)在上面有记录。
2.7.1从U-Boot写入SPI
AM57x和DRA7x平台注意事项:
在U-Boot构建中,MLO.byteswap 和 u-boot.img文件是要写入的文件。
在这个例子中,我们从SD卡加载所有文件,但是它们也可以通过网络(上面的文档)或其他存在的接口轻松加载。
此时,SPI mtd分区映射还没有更新为包含设备树的示例位置。

U-Boot # mmc rescan
U-Boot # sf probe 0
U-Boot # sf erase 0 +80000
U-Boot # fatload mmc 0 ${loadaddr} MLO.byteswap
U-Boot # sf write ${loadaddr} 0 ${filesize}
U-Boot # fatload mmc 0 ${loadaddr} u-boot.img
U-Boot # sf write ${loadaddr} 0x20000 ${filesize}
U-Boot # sf erase 80000 +${spiimgsize}
U-Boot # fatload mmc 0 ${loadaddr} zImage
U-Boot # sf write ${loadaddr} ${spisrcaddr} ${filesize}

Keystone-2 (K2H/K/E/L/G)平台注意事项:
在U-Boot构建中,u-boot-spi.gph文件就是要写入的文件。
在本例中,我们通过netowrk从tftp服务器加载文件。
该系列命令将u-boot映像烧录到SPI NOR flash

U-Boot # env default -f -a
U-Boot # setenv serverip 
U-Boot # setenv tftp_root 
U-Boot # setenv name_uboot u-boot-spi.gph
U-Boot # run get_uboot_net
U-Boot # run burn_uboot_spi

2.7.2从SPI引导
在支持SPI的每个主板的默认环境中,都有一个名为spiboot的引导命令,它将自动加载内核并引导。要获得每个命令的确切细节,请使用spiboot变量上的printenv,然后依次使用该命令的其他子节。这里最重要的变量是spiroot和spirootfstype。对于Keystone-2平台,使用SW1 dip开关设置将其配置为ARM SPI引导模式。请参考每个Keystone-2 EVM的硬件设置。
2.8 OSPI / QSPI
OSPI/QSPI是一种类似SPI的串行外设接口,主要区别在于支持八进制/四进制读取,与传统SPI使用2条线相比,使用8/4数据线进行读取。本节介绍如何将文件写入QSPI设备,并使用QSPI上的根文件系统加载并引导Linux内核。此时,在支持的硬件上执行这些操作不需要特殊的U-Boot版本。为了简单起见,我们假设文件是从SD卡加载的。使用网络接口(如适用)见上文。2.8.1。AM654 / J721E支持
ROM支持从OSPI从偏移0x0引导。
闪动图像到OSPI
下面的命令可以用于下载tiboot3.bin, tispl.bin和u-boot。img通过tftp,然后flash到OSPI在各自的地址。

=> sf probe
=> tftp ${loadaddr} tiboot3.bin
=> sf update $loadaddr 0x0 $filesize
=> tftp ${loadaddr} tispl.bin
=> sf update $loadaddr 0x80000 $filesize
=> tftp ${loadaddr} u-boot.img
=> sf update $loadaddr 0x280000 $filesize
=> tftp ${loadaddr} sysfw.itb
=> sf update $loadaddr 0x6C0000 $filesize

Flash Layout for OSPI
0x0 ±---------------------------+
| ospi.tiboot3(512K) |
| |
0x80000 ±---------------------------+
| ospi.tispl(2M) |
| |
0x280000 ±---------------------------+
| ospi.u-boot(4M) |
| |
0x680000 ±---------------------------+
| ospi.env(128K) |
| |
0x6A0000 ±---------------------------+
| ospi.env.backup (128K) |
| |
0x6C0000 ±---------------------------+
| ospi.sysfw(1M) |
| |
0x7C0000 ±---------------------------+
| padding (256k) |
0x800000 ±---------------------------+
| ospi.rootfs(UBIFS) |
| |
±---------------------------+
内核映像和DT应该出现在UBIFS ospi的/boot文件夹中。rootfs和SD卡的情况一样。U-Boot为rootfs查找名为“rootfs”的UBI卷。
要从OSPI引导内核,在U-Boot提示符下:
=> setenv boot ubi
=> boot
2.8.2. DRA7xx support
Memory Layout of QSPI Flash
±---------------+ 0x00000
| MLO |
| |
±---------------+ 0x040000
| u-boot.img |
| |
±---------------+ 0x140000
| DTB blob |
±---------------+ 0x1c0000
| u-boot env |
±---------------+ 0x1d0000
| u-boot env |
| (backup) |
±---------------+ 0x1e0000
| |
| uImage |
| |
| |
±---------------+ 0x9e0000
| |
| other data |
| |
±---------------+
从U-Boot写入QSPI
注意:
从U-Boot构建,MLO和U-Boot.img文件是要写入的文件。
在这个例子中,我们从SD卡加载所有文件,但是它们也可以通过网络(上面的文档)或其他存在的接口轻松加载。
写入MLO和u-boot.img二进制文件。
对于QSPI_1,使用dra7xx_evm_config构建U-Boot

U-Boot # mmc rescan
U-Boot # fatload mmc 0 ${loadaddr} MLO
U-Boot # sf probe 0
U-Boot # sf erase 0x00000 0x100000
U-Boot # sf write ${loadaddr} 0x00000 ${filesize}
U-Boot # fatload mmc 0 ${loadaddr} u-boot.img
U-Boot # sf write ${loadaddr} 0x40000 ${filesize}

更改SW2[5:0] = 110110用于qspi引导。
对于QSPI_4,使用dra7xx_evm_qspiboot_config构建U-Boot

U-Boot # mmc rescan
U-Boot # fatload mmc 0 ${loadaddr} MLO
U-Boot # sf probe 0
U-Boot # sf erase 0x00000 0x100000
U-Boot # sf write ${loadaddr} 0x00000 0x10000
U-Boot # fatload mmc 0 ${loadaddr} u-boot.img
U-Boot # sf write ${loadaddr} 0x40000 0x60000

更改SW2[5:0] = 110111用于qspi引导。
使用DFU写入QSPI
设置:连接EVM的usb0端口到ubuntu主机PC。确保安装了dfu-util工具。

#sudo apt-get install dfu-util
From u-boot:
U-Boot # env default -a
U-Boot # setenv dfu_alt_info ${dfu_alt_info_qspi}; dfu 0 sf "0:0:64000000:0"

从ubuntu PC:使用dfu-util实用程序将二进制文件闪存到QSPI flash。。

# sudo dfu-util -l
(C) 2005-2008 by Weston Schmidt, Harald Welte and OpenMoko Inc.
(C) 2010-2011 Tormod Volden (DfuSe support)
This program is Free Software and has ABSOLUTELY NO WARRANTY
dfu-util does currently only support DFU version 1.0
Found DFU: [0451:d022] devnum=0, cfg=1, intf=0, alt=0, name="MLO"
Found DFU: [0451:d022] devnum=0, cfg=1, intf=0, alt=1, name="u-boot.img"
Found DFU: [0451:d022] devnum=0, cfg=1, intf=0, alt=2, name="u-boot-spl-os"
Found DFU: [0451:d022] devnum=0, cfg=1, intf=0, alt=3, name="u-boot-env"
Found DFU: [0451:d022] devnum=0, cfg=1, intf=0, alt=4, name="u-boot-env.backup"
Found DFU: [0451:d022] devnum=0, cfg=1, intf=0, alt=5, name="kernel"
使用备用接口号(alt=<x>)将二进制文件闪存到相应的区域。
# sudo dfu-util -c 1 -i 0 -a 0 -D MLO
# sudo dfu-util -c 1 -i 0 -a 1 -D u-boot.img
# sudo dfu-util -c 1 -i 0 -a 2 -D 
# sudo dfu-util -c 1 -i 0 -a 5 -D uImage

从QSPI从u-boot引导
默认环境不包含QSPI引导命令。下面的示例使用内核中找到的分区表。

U-Boot # sf probe 0
U-Boot # sf read ${loadaddr} 0x1e0000 0x800000
U-Boot # sf read ${fdtaddr} 0x140000 0x80000
U-Boot # setenv bootargs console=${console} root=/dev/mtdblock19 rootfstype=jffs2
U-Boot # bootz ${loadaddr} - ${fdtaddr}

从SPL从QSPI引导(单阶段或Falcon模式)
在这种引导模式下,SPL(第一阶段引导加载程序)直接引导Linux内核。可选地,为了进入U-Boot,在按下串行终端上的“c”键时重置主板。当在U-Boot构建中启用falcon模式(通常是默认启用的)时,MLO检查在定义的偏移位置是否存在有效的uImage。如果uImage存在,它将直接引导。如果没有找到有效的uImage, MLO将返回到引导u-boot.img。
对于QSPI单阶段或Falcon模式,应该启用

CONFIG_QSPI_BOOT。
Menuconfig->Bood media
   [ ] Support for booting from NAND flash
   ..
   [*] Support for booting from QSPI flash
   [ ] Support for booting from SATA
   ...

MLO,u-boot.img(可选)、DTB、UIImage存储在QSPI闪存中。有关偏移量的详细信息,请参阅“内存布局”部分。例如,要将二进制文件闪存到QSPI,可以使用DFU。
QSPI引导使用uImage。构建内核uImage。您需要将U-Boot工具mkimage保存在$PATH中

# make uImage modules dtbs LOADADDR=80008000

如果内核没有使用CONFIG_CMDLINE来设置正确的引导程序,那么使用fdtput主机实用程序在DTB文件中选择的节点中添加所需的引导程序。例如,对于DRA74x EVM:

# fdtput -v -t s arch/arm/boot/dts/dra7-evm.dtb "/chosen" bootargs "console=ttyO0,115200n8 root="

将环境变量“boot_os”设置为1。
从u-boot提示符

=> setenv boot_os 1
=> saveenv

2.8.3 AM43xx支持
在AM43xx平台上使用QSPI是就地执行的,U-Boot是直接引导的。
从U-Boot写入QSPI
注意:
在U-Boot构建中,要写入的是U-Boot .bin文件。
在这个例子中,我们从SD卡加载所有文件,但是它们也可以通过网络(上面的文档)或其他存在的接口轻松加载。

U-Boot # mmc rescan
U-Boot # fatload mmc 0 ${loadaddr} u-boot.bin
U-Boot # sf probe 0
U-Boot # sf erase 0x0 0x100000
U-Boot # sf write ${loadaddr} 0x0 ${filesize}

从QSPI引导
默认环境不包含QSPI引导命令。下面的示例使用内核中找到的分区表。

U-Boot # sf probe 0
U-Boot # sf read ${loadaddr} 0x1a0000 0x800000
U-Boot # sf read ${fdtaddr} 0x100000 0x80000
U-Boot # setenv bootargs console=${console} spi-ti-qspi.enable_qspi=1 root=/dev/mtdblock6 rootfstype=jffs2
U-Boot # bootz ${loadaddr} - ${fdtaddr}

2.9 NOR
本节介绍如何将文件写入NOR设备,并使用NOR上的根文件系统加载和引导Linux内核。为了使NOR对U-Boot可见,需要在受支持的硬件上构建特殊的U-Boot。下表列出了see NOR的构建,在某些情况下也使用theit来代替默认的NAND。最后,为了简单起见,我们假设文件是从SD卡加载的。使用网络接口(如果适用)在上面有记录。
2.9.1从U-Boot写入NOR
注意:
在U-Boot构建中,要编写的是U-Boot .bin文件。
在这个例子中,我们从SD卡加载所有文件,但是它们也可以通过网络(上面的文档)或其他存在的接口轻松加载。
此时,NOR mtd分区映射还没有更新以包含设备树的示例位置。

Board	Config target
AM335x EVM	am335x_evm_nor_config / am335x_evm_norboot_config
U-Boot # mmc rescan
U-Boot # load mmc 0 ${loadaddr} u-boot.bin
U-Boot # protect off 08000000 +4c0000
U-Boot # erase 08000000 +4c0000
U-Boot # cp.b ${loadaddr} 08000000 ${filesize}
U-Boot # fatload mmc 0 ${loadaddr} zImage
U-Boot # cp.b ${loadaddr} 080c0000 ${filesize}

2.9.2从NOR启动
在默认环境中,没有启动的快捷方式。需要传递root=/dev/mtdblockN,其中N是bootargs中rootfs分区的数量。
2.10 UART
本节介绍如何使用UART加载文件,将板引导到U-boot。在此之后,用户应该知道如何继续加载文件。
2.10.1从控制台UART引导U-Boot
在某些情况下,我们支持通过控制台UART加载SPL和U-Boot。您需要使用spl/u-boot-spl.bin and u-boot.img 启动。根据TRM,文件是通过X-MODEM协议在115200波特8停止位不奇偶校验(相同的使用它的控制台)。而SPL则期望通过u-boot发送。以相同的速度,但通过y调制解调器。一个来自主机的会话示例,假设console在ttyUSB0上并且已经配置好,并且安装了lrzsz包

$ sx -kb /path/to/u-boot-spl.bin < /dev/ttyUSB0 > /dev/ttyUSB0
$ sx -kb --ymodem /path/to/u-boot.img < /dev/ttyUSB0 > /dev/ttyUSB0

在基于K3的平台上,ROM支持通过X-Modem协议从MCU_UART0引导。从UART到U-Boot(适当的)提示符的整个引导过程会经历不同的阶段,并使用不同的UART外围设备,如下所示:

WHO	Loading WHAT	HW Module	Protocol
Boot ROM	tiboot3.bin	MCU_UART0	X-Modem
R5 SPL	sysfw.itb	MCU_UART0	Y-Modem
R5 SPL	tispl.bin	MAIN_UART0	Y-Modem
A53/A72 SPL	u-boot.img	MAIN_UART0	Y-Modem

UART_BOOT_MAIN_UART和UART_BOOT_MCU_UART应该设置为诸如/dev/ttyUSBx.这样的串行端口

$ sb --xmodem $OUT_R5/tiboot3.bin > $UART_BOOT_MCU_UART < $UART_BOOT_MCU_UART
$ sb --ymodem $SYSFW_ITB > $UART_BOOT_MCU_UART < $UART_BOOT_MCU_UART
$ sb --ymodem $OUT_AXX/tispl.bin > $UART_BOOT_MAIN_UART < $UART_BOOT_MAIN_UART
$ sb --xmodem $OUT_AXX/u-boot.img > $UART_BOOT_MAIN_UART < $UART_BOOT_MAIN_UART

2.11SATA
请注意
J721E平台不支持SATA。
SATA和eSATA设备在U-boot中显示为SCSI设备。
2.11.1。查看SATA设备
要查看U-boot看到的所有SCSI设备,可以使用“SCSI info”命令。
该命令在AM57x通用EVM上运行时的输出如下所示。

scsi part
Device 0: (0:0) Vendor: ATA Prod.: PLEXTOR PX-64M6M Rev: 1.08
            Type: Hard Disk
            Capacity: 61057.3 MB = 59.6 GB (125045424 x 512)

设备0表示scsi设备的实例。因此,在后面的命令中,当看到“”参数时,请将其替换为适当的设备号。
2.11.2查看分区
要查看SATA设备上找到的所有分区,可以使用命令“scsi part ”。
该命令在AM57x通用EVM上运行时的输出如下所示。

Partition Map for SCSI device 0  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID            Type
  1     2048            161793          6cc50771-01     0c Boot
  2     165888          33552385        6cc50771-02     83
  3     33720320        91325104        6cc50771-03     83

上面的所有条目表示存在于特定scsi设备上的不同分区。要引用特定的分区,用户将引用上面所示的部分号。在下面所示的命令中,应该替换为从这个表中可以看到的适当分区号。
2.11.3识别分区文件系统类型
如上所示,可以使用“scsi part ”命令查看特定scsi设备上的所有分区。但是,要使用的正确命令取决于每个分区被格式化成的文件系统类型。
在“scsi part ”命令中,可以在type列下找到分区类型。Type列下的值称为分区id。根据分区id,将指定用于读写分区的命令。分区id“0c”指的是FAT32分区。分区id“83”指的是ext2、ext3和ext4所属的本地Linux文件系统。到这里查找分区id的完整列表。
2.11.4查看、读写分区
根据分区的文件系统类型,将取决于读取和写入分区所使用的确切命令。最常见的两个分区是FAT32、EXT2和EXT4。幸运的是,查看、读取和写入分区的命令看起来都是一样的。查看分区使用ls,读取文件为加载,写入文件为写入。根据文件系统类型,将替换为fat、ext2和ext4。
2.11.5查看分区内容
要查看FAT32分区的内容,用户可以使用“fatls scsi :”
下面的命令列出了AM57x通用EVM上SCSI设备0分区1的内容:

=> fatls scsi 0:1
   110578   test
1 file(s), 0 dir(s)

文件写入分区
要在EXT4分区上写入文件,用户必须首先读取要写入内存的文件,然后还要知道文件的大小。幸运的是,U-boot自动将环境变量“filesize”设置为通过U-boot load命令加载到内存中的文件的大小。
要写入ext4分区,用户将执行以下命令:ext4write scsi
在上面的命令中,是指文件已经加载到内存中的地址。绝对文件名路径必须以/开头,以指示根目录。Filesize是要写入的字节数。
下面是一个将先前加载到内存中的文件“tester”写入EXT4分区的示例

=> ext4write scsi 0:3 ${loadaddr} /tester ${filesize}
File System is consistent
update journal finished
110578 bytes written in 2650 ms (40 KiB/s)

2.12 UFS
通用Flash子系统(UFS)设备显示为与上一节中的SATA类似的scsi设备。初始化所有ufs设备的另一个命令是:

::=> ufs init Device at ufs@4e84000 up at:[RX, TX]: gear=[3,3], lane[2,2], pwr[FAST MODE, FAST MODE], rate = 2

然后我们可以继续’ scsi scan '看附件设备:

=> scsi scan
  scanning bus for devices...
Device 0: (0:0) Vendor: TOSHIBA Prod.: THGAF8G8T23BAILB Rev: 0300
          Type: Hard Disk
          Capacity: 31.9 MB = 0.0 GB (8191 x 4096)
Device 0: (0:1) Vendor: TOSHIBA Prod.: THGAF8G8T23BAILB Rev: 0300
          Type: Hard Disk
          Capacity: 30499.9 MB = 29.7 GB (7807999 x 4096)

上一节中详细介绍的所有其余scsi命令也适用。
有关UFS的更多信息,请参阅内核UFS指南。
2.13 DDR3 ECC
请注意
下面描述的DDR3 ECC特性对Keystone-II设备启用。
2.13.1在Keystone-II中的DDR3 ECC
一些TI SoC设备启用了DDR ECC。Keystone-II设备(K2H/K2E/K2G)启用DDR3错误检测和纠正功能。DDR3控制器支持ECC数据写入或从SDRAM读取,并通过编程ECC控制寄存器启用。对于K2H和K2E, 8位ECC计算在64位数据量子之上,而对于K2G, 4位ECC计算在32位数据之上。ECC计算的所有访问是在地址范围内的ECC保护。1位错误可被ECC纠正,2位错误不可纠正,将被软件视为不可恢复错误并触发设备复位。
2.13.1.1 DDR3 ECC处理
U-boot检查DDR3控制器是否支持ECC RMW。如果ECC RMW不支持(在K2H PG1中)。, U-boot将默认禁用ECC,否则总是启用ECC(在K2H PG2.0、K2E和K2G设备中)。
在ECC初始化期间,U-boot在ECC启用后使用EDMA通道将整个内存(最多8GB)填零。对于K2H设备,U-boot配置芯片级中断控制器,将DDR3 ECC错误中断路由到ARM中断控制器。对于K2E和K2G设备,由于DDR3 ECC错误中断直接路由到ARM中断控制器,因此不需要配置芯片级中断控制器。
添加一个DDR3命令,通过在特定地址生成DDR数据中的位错误来模拟ECC错误。命令格式为:

ddr ecc_err <addr in hex> <bit_err in hex>

该命令将从中读取32位数据,并将(data ^ bit_err)写回
例如:
ddr ecc_err 0x90000000 0x1(这将在ddr地址0x9000_0000中数据的第0位产生1位错误)
ddr ecc_err 0xa0000000 0x1001(这将在ddr地址0xa000_0000中数据的0位和3位上产生2位错误)
还引入了一个新的环境变量“ecc_test”来测试ECC。默认情况下,ecc_test = 0,任何检测到的2位错误都将重置设备。如果ecc_test = 1, U-boot将绕过该错误,继续引导Linux内核,以便Linux内核可以在中断服务中处理该错误。
请注意
Keystone-II Linux内核中的DDR3 ECC处理
Linux内核请求一个IRQ处理程序为DDR3 ECC错误中断,处理程序检查DDR3控制器中断状态寄存器,如果错误是2位错误,Linux内核将重新启动设备。用户也可以使用用户模式命令读取DDR3 ECC寄存器(如1位错误计数寄存器等),DDR3控制器寄存器和中断映射定义在设备树绑定的sysctrl节点:

E.g. K2H SOC device tree:
sysctrl {
      reg = <0x21010000 0x0200>; /* DDR3 controller reg */
      interrupts = <0 24 0xf01    /* L1L2 ECC error interrupt */
                    0 448 0xf01>; /* DDR3 ECC error interrupt */
};

2.14 HyperBus和HyperFlash
hybibus是主机系统主接口和一个或多个从机接口之间的低信号计数、高性能双数据速率(DDR)总线接口。它是一个8位数据总线(DQ[7:0]),带有读写数据选通(RWDS)信号和单端时钟(3.0V部分)或差分时钟(1.8V部分)。它使用ChipSelect线来选择b/w多个从站。在总线级别,它遵循hybibus规范中描述的单独协议。
HyperFlash是一种基于NOR-flash的设备存储。HyperFlash遵循CFI AMD/Fujitsu扩展命令集(0x0002),类似于现有的并行NORs。由于hybibus是x8 DDR总线,因此它相当于每clk x16并行NOR flash wrt位。但是Hyperbus的工作频率很高。
在TI的J721E EVM上的HyperFlash连接到超总线内存控制器,支持内存映射IO访问flash。HyperFlash在MTD框架下得到支持,可以使用U-Boot的标准MTD命令来访问HyperFlash
支持的设备- J721E EVM
要列出检测到的HyperFlash设备:

=> mtd list
List of MTD devices:
* nor0
 - type: NOR flash
 - block size: 0x40000 bytes /* Each erase sector size is of 256KB */
 - min I/O: 0x1 bytes
 - 0x000000000000-0x000004000000 : "nor0" /* Detected 64MB devices labeled as "nor0" */

下面的例子展示了如何从U-Boot提示符中擦除和写入不同的引导映像到HyperFlash。擦除必须是擦除扇区大小的倍数。

=> mtd erase nor0 0 0x40000 /* Erase from offset 0 to 256KB of HyperFlash labeled nor0 */
Erasing 0x00000000 ... 0x0003ffff (1 eraseblock(s))
=> fatload mmc 1 0x82000000 tiboot3.bin /* Load an img from SD into DDR to flash into HyperFlash */
180932 bytes read in 10 ms (17.3 MiB/s)
=> mtd write nor0  0x82000000 0x0 $filesize /* Write the loaded image into HyperFlash labeled nor0 */
Writing 180932 byte(s) at offset 0x00000000
=>

下面的示例展示了如何读取数据

=> mtd read nor0 0x82000000 0x0 0x40000 /* Read from offset 0 to 0x4000 to DDR address 0x82000000 from nor0 */
Reading 262144 byte(s) at offset 0x00000000

下面的命令可以用于下载tiboot3.bin, tispl.bin和u-boot.img通过tftp,然后flash到HyperFlash在各自的地址。

=> mtd erase nor0 0 0x800000
=> tftp ${loadaddr} tiboot3.bin
=> mtd write nor0 $loadaddr 0x0 $filesize
=> tftp ${loadaddr} tispl.bin
=> mtd write nor0 $loadaddr 0x80000 $filesize
=> tftp ${loadaddr} u-boot.img
=> mtd write nor0 $loadaddr 0x280000 $filesize
=> tftp ${loadaddr} sysfw.itb
=> mtd write nor0 $loadaddr 0x6C0000 $filesize

HyperFlash的Flash布局
下面是HyperFlash的布局,以便从HyperFlash启动:

     0x0 +----------------------------+
         |     hbmc.tiboot3(512K)     |
         |                            |
 0x80000 +----------------------------+
         |     hbmc.tispl(2M)         |
         |                            |
0x280000 +----------------------------+
         |     hbmc.u-boot(4M)        |
         |                            |
0x680000 +----------------------------+
         |     hbmc.env(128K)         |
         |                            |
0x6C0000 +----------------------------+
         |      hbmc.sysfw(1M)        |
         |                            |
0x7C0000 +----------------------------+
         |      padding (256k)        |
0x800000 +----------------------------+
         |     hbmc.rootfs(UBIFS)     |
         |                            |
         +----------------------------+

2.15 REMOTEPROC
本节介绍如何从U-Boot提示符初始化、加载、启动和停止远程内核。U-boot提供以下remotecores支持:
Cortex-R5F步调一致
分裂模式下的Cortex-R5F
C66x数字信号处理器
C71x数字信号处理器
2.15.1初始化
U-Boot支持一次性初始化所有可用的RemoteCore或根据DT别名id初始化单个core。
以下命令将初始化所有可用的远程核心:

=> rproc init

下面的命令只初始化给定的远程核心

=> rproc init <id>

下面的命令列出了系统中所有可用的/初始化的远程存储。
=> rproc list
0 - Name:‘r5f@41000000’ type:‘internal memory mapped’ supports: load start stop reset
1 - Name:‘r5f@41400000’ type:‘internal memory mapped’ supports: load start stop reset
2 - Name:‘r5f@5c00000’ type:‘internal memory mapped’ supports: load start stop reset
3 - Name:‘r5f@5d00000’ type:‘internal memory mapped’ supports: load start stop reset
4 - Name:‘r5f@5e00000’ type:‘internal memory mapped’ supports: load start stop reset
5 - Name:‘r5f@5f00000’ type:‘internal memory mapped’ supports: load start stop reset
6 - Name:‘dsp@4d80800000’ type:‘internal memory mapped’ supports: load start stop reset
7 - Name:‘dsp@4d81800000’ type:‘internal memory mapped’ supports: load start stop reset
8 - Name:‘dsp@64800000’ type:‘internal memory mapped’ supports: load start stop reset
2.15.2 Loading
初始化后,远程存储可以与相关的映像一起加载。确保只有在初始化核心后才加载图像。
=> load mmc 1:2 0x90000000 /lib/firmware/j7-main-r5f0_0-fw
2536540 bytes read in 112 ms (21.6 MiB/s)
=> rproc load 2 0x90000000 0x${filesize}
Load Remote Processor 2 with data@addr=0x90000000 2536540 bytes: Success!
2.15.3. Starting
可以使用以下命令启动成功加载的远程存储。
=> rproc start 2
2.15.4 Stop
可以使用以下命令停止正在运行的远程服务器。
=> rproc stop 2
确保所有命令都按照上述给定的顺序运行。目前在U-boot中不支持IPC。

你可能感兴趣的:(uboot,u-boot)