2021-02-22

TI jacinto uboot – 下

3.1.1.11. SATA
请注意
J721E平台不支持SATA。
U-boot中SATA和eSATA设备显示为SCSI设备.
3.1.1.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设备的实例。因此,在后面的命令中,当看到“”参数时,用适当的设备号替换它。
3.1.1.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设备上存在的不同分区。要引用特定分区,用户将引用上面显示的部件号。在下面显示的命令中,应该替换为从这个表中看到的适当的分区号。
3.1.1.11.3. 标识分区文件系统类型
如上所示,“scsi part ”命令可用于查看特定scsi设备上的所有可用分区。但是,要使用的正确命令取决于每个分区的格式化文件系统类型。
在“scsi part ”命令中,可以在type列下找到分区类型。Type列下的值被称为partition id。根据partition id将指定用于读写分区的命令。分区id为“0c”表示FAT32分区。分区id为“83”表示ext2、ext3和ext4所属的本地Linux文件系统。转到此处查找分区ID的完整列表。

3.1.1.11.4. 查看、读取和写入分区
分区的文件系统类型取决于读取和写入分区所使用的确切命令。最常见的两个分区是FAT32、EXT2和EXT4。幸运的是,查看、读取和写入分区的命令看起来都一样。查看分区使用ls,读取文件是load,写入文件是write。根据文件系统类型,用fat、ext2和ext4替换。
3.1.1.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命令加载到内存中的文件的filesize。
要写入ext4分区,用户将执行以下命令:ext4write scsi <dev>:<partition> <ddr address> <absolute filename path> <filesize>
在上面的命令中,指的是文件已经加载到内存中的地址。绝对文件名路径必须以/开头以指示根。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)

3.1.1.12. UFS
通用闪存子系统(UFS)设备显示为scsi设备,类似于上一节中的SATA。初始化所有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指南.
3.1.1.13. DDR3 ECC公司
注意
下面描述的DDR3 ECC功能已为Keystone II设备启用。
3.1.1.13.1. Keystone-II中的DDR3 ECC
一些TI SoC设备启用了DDR ECC。Keystone-II设备(K2H/K2E/K2G)启用DDR3错误检测和纠正功能。DDR3控制器对从SDRAM写入或读取的数据支持ECC,并通过编程ECC控制寄存器启用。对于K2H和K2E,8位ECC是在64位数据量上计算的,但是对于K2G,4位ECC是在32位数据上计算的。ECC是为所有在ECC保护的地址范围内的访问计算的。1位错误可通过ECC纠正,2位错误不可纠正,软件将其视为不可恢复错误,并触发设备复位。
3.1.1.13.1.1. DDR3 ECC处理
Keystone-II U-boot检查DDR3控制器是否支持ECC RMW。如果不支持ECC RMW(在K2H PG1.x设备中),则默认情况下U-boot将禁用ECC,否则它将始终启用ECC(在K2H PG2.0、K2E和K2G设备中)
在ECC初始化期间,启用ECC后,U-boot使用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 (this will genereate a 1-bit error on bit 0 of the data in ddr address 0x9000_0000)
ddr ecc_err 0xa0000000 0x1001 (this will genereate 2-bit error on bit 0 & 3 of the data in ddr address 0xa000_0000)

同时引入了一个新的环境变量“ecc_test”来测试ECC。默认情况下,ecc_test = 0,任何2位错误检测都将重置设备。如果ecc_test = 1,U-boot将绕过错误并继续引导Linux内核,以便Linux内核可以处理中断服务中的错误。
注意
Keystone-II Linux内核中的DDR3 ECC处理
Linux内核为DDR3 ECC错误中断请求一个IRQ处理程序,处理程序检查DDR3控制器中断状态寄存器,如果错误是2位错误,Linux内核将重新启动设备。用户也可以使用用户模式命令读取DDR3 ECC寄存器(如:1比特错误计数寄存器等),DDR3控制器寄存器和中断映射在设备树绑定的sysctrl节点中定义:
例如:K2H SOC设备树:

sysctrl {
      reg = <0x21010000 0x0200>; /* DDR3 controller reg */
      interrupts = <0 24 0xf01    /* L1L2 ECC error interrupt */
                    0 448 0xf01>; /* DDR3 ECC error interrupt */
};

3.1.1.14. HyperBus和HyperFlash
HyperBus是主机系统主接口和一个或多个从接口之间的低信号计数、高性能双数据速率(DDR)总线接口。它是一个8位数据总线(DQ[7:0]),具有读写数据选通(RWDS)信号和单端时钟(3.0V部分)或差分时钟(1.8V部分)。它使用ChipSelect行选择b/w多个从机。在总线级,它遵循HyperBus规范中描述的单独协议。
HyperFlash是一种基于NOR flash的设备存储。HyperFlash遵循CFI AMD/Fujitsu扩展命令集(0x0002),类似于现有的并行NORs。由于Hyperbus是x8 DDR总线,它相当于x16并行NOR flash wrt位/clk。但Hyperbus的工作频率非常高。
TI的J721E EVM上的HyperFlash连接到HyperBus内存控制器,该控制器支持对flash的内存映射IO访问。在MTD框架下支持HyperFlash,可以使用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" */

请注意
在J721E EVM上,SW3.1应设置为On位置以选择HyperFlash.
下面的示例演示如何从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

将图像闪烁到HyperFlash
下面的命令可以用来通过tftp下载tiboot3.bin, tispl.bin and u-boot.img,然后在相应的地址将其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)     |
         |                            |
         +----------------------------+

J721E EVM的引导模式开关设置
写入映像后,将EVM上的引导模式开关更改为以下,以便在83MHz下从HyperFlash启动:

Switch No.	1	2	3	4	5	6	7	8	9	10
SW8	OFF	OFF	OFF	OFF	OFF	OFF	OFF	OFF	OFF	OFF
SW9	OFF	OFF	OFF	OFF	OFF	OFF	OFF	OFF	OFF	OFF
SW3	ON	ON	ON	ON	OFF	OFF	ON	OFF	ON	OFF

3.1.1.15。REMOTEPROC
本节介绍如何在U-Boot提示符下初始化、加载、启动和停止远程内核。U-boot支持以下remotecores:

• Cortex-R5F in Lockstep more
• Cortex-R5F in split mode
• C66x DSP
• C71x DSP
3.1。初始化
U-Boot支持在一个go中初始化所有可用的remotecores或基于DT别名id初始化单独的核心。
下面的命令将初始化所有可用的远程核心:

=> rproc init

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

=> rproc init <id>

下面的命令列出了系统中所有可用的/初始化的remotecores.
=> 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
3.1. 加载
一旦初始化,remotecores就可以加载相关的映像。确保只有在初始化核心后才加载映像。

=> 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!

3.1. 启动
可以使用以下命令启动已成功加载的remotecore。

=> rproc start 2

3.1. 停止
可以使用以下命令停止正在运行的remotecore

=> rproc stop 2

确保所有命令都按照上面给出的顺序运行。目前U-boot不支持IPC.

3.1.1.16. Uboot SPL调试技巧
下一节演示如何将板连接到CCS并加载SPL符号以进行调试。在下面的实验中,用户需要从SD卡启动他们的主板。
3.1.1.16.1. 步骤1:下载CCS
1.请从以下链接下载CCS

: http://software-dl.ti.com/ccs/esd/documents/ccs_downloads.html

注意:我们将在Linux机器上构建Uboot,建议在同一操作系统(OS)上安装CCS。如果CCS没有安装在同一操作系统上,CCS将无法定位代码文件。请按照以下链接上的Linux说明操作: http://software-dl.ti.com/ccs/esd/documents/ccs_linux_host_support.html
3.1.1.16.2. 步骤2:创建目标配置文件
1.第一步是在CCS中创建目标配置文件。导航至 “View”-> “Target Configurations”:

  1. 右键单击“Target Configurations”窗口,选择“New Target Configuration”:

  2. 为目标配置创建一个名称:

4.选择合适的SoC和JTAG。注意:如果我们选择SoC名称,则不会加载GEL文件。但是,如果我们选择board选项,默认情况下会加载GEL文件。在下面的示例中,如果选择了GPEVM_AM65x or IDK_AM65x,则会在配置中自动启用GEL文件。调试Uboot时,建议避免使用GEL文件,因为Uboot负责初始化外围设备:

5.下一步,单击“保存并测试连接”以确保CCS能够与调试器通信:

3.1.1.16.3. 步骤3:加载符号文件
在加载符号之前,测试代码将添加到SPL代码中。测试代码将在其自身内循环,打破循环的唯一方法是通过CCS更改程序计数器。对于目前的实验,AM65EVM是使用,但同样的实验可以在其他板上进行。以下测试代码添加到文件<ti_sdk_dir>/board-support/<u-boot_version>/arch/arm/mach-k3/am6_init.c中的“board_init_f”函数中:

store_boot_index_from_rom();

/* 使所有控制模块寄存器都可访问*/

ctrl_mmr_unlock();

asm("test: nop");
asm("       nop");
asm("  b test ");
asm(" nop");
asm(" nop");

setup_am654_navss_northbridge();

如果用户正在使用AM335x/AM437x/AM57xx,测试代码可以添加到文件<ti_sdk_dir>/board-support/<u-boot_version>/arch/arm/mach-omap2/hwinit-common.c中的“early_system_init”函数中。测试代码在所有平台上的位置都会因我们尝试调试的SPL部分而异。
1.编译Uboot有两种方法:method1和method2。这两种方法都将生成SPL调试所需的符号文件。
2.在AM335x/AM437x/AM57xx上,符号文件位于以下目录“<ti_sdk_dir>/board-support/<u-boot_version>/spl/u-boot-spl”。对于AM654x,符号文件位于以下目录“<ti_sdk_dir>/board-support/u-boot_build/r5/spl/u-boot-spl”。
3. 构建Uboot后,将相关映像复制到SD卡上。对于AM335x/AM437x/AM57xx,复制MLO and u-boot.img到SD卡。对于AM65x,复制sysfw.itb, tiboot3.bin, tispl.bin and u-boot.img到SD卡。
4. 安装SD卡并上电。
5. 在CCS上,启动步骤2中创建的目标配置文件:

  1. 成功发布后,连接到ARM核心之一。在AM65x上,初始的SPL代码在R5上执行,因此用户将连接到R5核心。对于AM335x/AM437/AM57xx,请连接到A8/A9/A15核心。

  2. 连接到核心后,点击“Run”-> “Load”->”Load Symbols…”:

8.加载代码后,CCS应找到源代码文件,并卡在先前添加的代码处:

9.要跳出循环,请更改寄存器窗口中的程序计数器:

此时,用户就可以逐步查看SPL代码并调试SPL中的问题。
注意:在像AM654x这样的K3系列设备上,DMSC的看门狗定时器部分由ROM bootcode默认启用,超时3分钟。看门狗定时器正常运行时由SYSFW (System Firmware)提供服务。如果在SYSFW加载前正在调试SPL,看门狗定时器不会自动得到服务,调试会话将在3分钟后重置。因此,建议在SYSFW启动后再开始调试SPL代码,以免影响看门狗定时器的复位。类似地,看门狗定时器也在AM335x/AM437x/AM57xx设备上启用,请参考gel文件中的“Disable_Watchdog()”函数。
3.1.1.17. 通过CodeComposer Studio(CCS)加载Uboot
下面的实验室将指导您使用CCS在AM437x EVM上加载SPL/U-Boot映像的过程。同样的过程也适用于其他电路板。
3.1.1.17.1. 第一步:软件下载
•根据Processor SDK Linux Getting Started Guide配置的Linux主机系统,安装了最新的Processor Software Development Kit(PSDK)和Code Composer Studios(CCS)。请参阅发行说明。本文档是使用Ubuntu 18.04、Processor SDK Linux 06.03和CCS 10.0编写的。
3.1.1.17.2 步骤2:测试硬件连接
•从主板上拆卸SD卡,并在主板和您的Linux主机之间建立USB电缆连接
•给单板上电
•打开终端,执行以下命令查找系统上可用的USB串口适配器:

“dmesg | grep tty”
 
 
[    0.000000] console [tty0] enabled
[    0.554632] 00:06: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[   29.566576] usb 2-1.6.1.1: pl2303 converter now attached to ttyUSB0

注意:ttyUSB将根据主机连接的不同而不同。
•启动串行终端(下面显示的终端是用$minicom -w -s创建的),并按如下方式配置:

•您现在应该可以看到一个正在打印“ccccc”的minicom窗口。继续,让这个控制台在后台运行。

3.1.1.17.3. 步骤3:构建SPL/Uboot映像
•打开另一个控制台终端并导航到已安装的最新PSDK
•将目录更改为Uboot源代码,并打开与主板相关的defconfig文件:“<psdk_dir>/board-support/u-boot-xxx+yyyy/configs/am43xx_evm_defconfig”
•在编译Uboot之前,请在am43xx_evm_defconfig文件中添加以下标志“CONFIG_OF_EMBED=y”。如果您参考<u-boot_dir>/README文件,它会提到“如果定义了此变量,u-boot将在其映像中嵌入设备树二进制文件”。请记住,这只适用于调试和开发,不建议用于生产。
•有两种编译Uboot的方法:method1和method2。这两种方法都将生成Uboot调试所需的必要文件
•成功编译后,我们感兴趣的3个映像:

Location	Image Name	Description
<psdk_dir>/board-support/u-boot-u-boot-xxx+yyyy/spl	u-boot-spl	Full SPL image containing all debug symbols
<psdk_dir>/board-support/u-boot-u-boot-xxx+yyyy/spl	u-boot-spl.bin	Stripped binary SPL image that can fit into the internal memory
<psdk_dir>/board-support/u-boot-u-boot-xxx+yyyy	u-boot	ELF image that contains debug symbols and the device tree files

3.1.1.17.4. 第4步:CCS配置
•启动CCS并选择File -> New -> Target Configuration File
•在New Target Configuration对话框中为配置指定名称。对于这个实验,我们将使用名称AM437x

•单击Use shared location,然后单击Finish
•你创建的AM437x配置现在会打开进行编辑。执行以下步骤完成目标器的配置。

  1. 在Connection下拉框中选择Texas Instruments XDS100v2 USB Emulator。如果您正在使用不同的模拟器,请选择该模拟器

  2. 在Board or Device选择列表中检查AM4378设备。请不要选择任何“IDK”或“EVM”选项,因为它将加载凝胶文件,我们不希望那样

  3. 单击屏幕右侧的Save按钮
    •你现在可以通过点击屏幕右边的test connection按钮来测试你的目标连接。

•关闭Test Connection对话框
3.1.1.17.5 第五步:改变ARM模式
•启动我们在上一步中创建的目标配置

  1. 单击View -> Target Configurations。这将在屏幕右侧打开一个名为Target Configurations的选项卡
  2. 展开User Defined列表
  3. 右键单击AM437x配置并选择Launch Selected configuration
    •视图应该已经更改为Debug标签(可能需要几分钟启动)

•右键单击CortxA9行项目,选择Connect Target
•使用CCS将处理器设置为ARM模式(不是THUMB模式),步骤如下:

  1. 选择“寄存器”选项卡

  2. 展开核心寄存器,在Core Registers内部展开CPSR列表

  3. 在CPSR寄存器列表中向下滚动,并将T寄存器从1更改为0。

  4. 您应该看到CPSR值发生了变化,以反映新值

•每次单板完全断电或复位时,都需要执行上述步骤
3.1.1.17.6 步骤6:加载SPL
•加载SPL二进制到内部芯片内存,请使用以下步骤:

  1. 单击Tools -> Load Memory。这里使用Load Memory工具,因为我们加载的是SPL二进制文件而不是ELF映像。这样做的原因是二进制文件的大小能够适应SoC的内部RAM

  2. 单击Browse按钮并导航到u-boot-spl.bin file文件(二进制位置参见步骤3)

  3. 选择u-boot-spl.bin文件,单击“OK”。对于文件类型,保留为“TI Raw Data”

  4. Start Address: 0x402F4000。这是u-boot源中定义的SPL二进制文件的起始地址。要确认起始地址,请导航到文件“<psdk_dir>/board-support/u-boot-u-boot-xxx+yyyy/spl/u-boot-spl.map” 和搜索“__start”

  5. 单击Finish,您将看到弹出一个框,显示内存加载操作

•为二进制文件加载符号,以允许源代码级的调试

  1. 单击Run -> Load -> Load Symbols……
  2. 在对话框中,单击Browse按钮
  3. 与前面一样,浏览到spl目录并将过滤器更改为All
  4. 选择u-boot-spl文件,它是ELF可执行文件,也包含这些符号,然后单击OK
  5. 确保代码偏移量和数据偏移量为空
    •现在二进制和符号已经加载,我们需要将程序计数器设置为SPL代码的开头。单击Registers选项卡,并在Core Registers列表中,将PC值更改为您之前输入的起始地址(0x402F4000)

•点击View -> Disassembly打开反汇编视图,确保PC等于0x402F4000

•此时,您可以*地逐步执行SPL代码
•继续并点击绿色的run按钮,让SPL完成运行
•一两秒钟后,按下黄色pause符号,暂停执行
您应该看到控制台窗口### ERROR ### Please RESET the board ###的输出

•这意味着SPL已经运行并试图从SD卡读取U-Boot映像,这是EVM的默认启动设置。处理器现在有了SPL上下文,这意味着单板可以进行U-Boot了。
重要提示:不要重置你的板子。如果您在此时重置了单板,则需要重新运行这些步骤并重新加载SPL以继续调试U-Boot
3.1.1.17.7 步骤7:加载Uboot镜像
•假设你已经执行了SPL,请使用以下步骤来加载U-Boot ELF映像:

  1. 在加载映像之前,请确保在CPSR寄存器中没有设置THUMB模式

  2. 单击Run -> Load -> Load Program……

  3. 单击Browse按钮,这次选择u-boot映像(二进制位置参见步骤3)

  4. 单击OK加载程序
    •由于加载了ELF映像,PC会自动设置。另外,请确保THUMB模式设置为0

•确定U-Boot重新定位偏移量。U-boot最初加载到低内存中,然后重新定位到高内存中,为Linux内核腾出空间。
1.既然已经加载了U-Boot,请单击green run arrow继续运行可执行文件。在minicom窗口中,您应该看到U-Boot开始运行,并在Uboot提示符下按enter
2.在minicom终端中,使用bdinfo命令查找relocaddr。您应该看到如下输出,其中显示的重定位地址为0xfff42000-此值随SDK的不同而变化

重要提示:您要获取relocaddr值,而不是“reloc off”值。
•重新加载U-Boot
1.重新加载图像之前,请确保CPSR寄存器中的THUMB mode设置为0
2.点击Run(运行)->Load(加载)->Reload Program(重新加载程序),完成加载
•现在U-Boot再次加载,我们需要根据之前确定的重新定位偏移重新加载符号。
1.单击Run -> Load -> Load Symbols…
2.确保Program file条目仍设置为u-boot文件。如果没有,请浏览到正确的文件。
3.在“代码偏移”字段中输入之前找到的偏移值。i.e. 0xfff42000
4.在数据偏移字段中输入之前找到的偏移值。i.e. 0xfff42000

您现在可以使用与SPL相同的方式进行step and step over操作
3.1.2. U-Boot发行说明
3.1.2.1. 构建信息
有关详细信息,请参阅Yocto build。
3.1.2.2. 已知问题
有关详细信息,请参阅已知问题。
3.1.3. U-Boot Splash屏幕
添加Splash屏幕

AM335x
下面的所有代码都基于Processor Linux SDK 03.02.00…05。
在drivers/video目录中有一个am335x的帧缓冲驱动程序,名为am3355x-fb.c。它调用board.c中的例程来设置LCDC和帧缓冲区。要使用它:
在configs目录中创建一个新的defconfig,或者只添加SPLASH to CONFIG_SYS_EXTRA_OPTIONS选项。在本例中,am335x_evm_defconfig被复制到一个名为am335x_evm_splash_defconfig的新文件中。

CONFIG_TARGET_AM335X_EVM=y
CONFIG_SPL_STACK_R_ADDR=0x82000000
CONFIG_DEFAULT_DEVICE_TREE="am335x-evm"
CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SYS_EXTRA_OPTIONS="NAND,SPLASH"
CONFIG_HUSH_PARSER=y
CONFIG_AUTOBOOT_KEYED=y
在include/configs/am335x_evm.h中,添加对启动屏幕、LCDC和gzip位图的支持。
/* Splash scrren support */
#ifdef CONFIG_SPLASH
#define CONFIG_AM335X_LCD
#define CONFIG_LCD
#define CONFIG_LCD_NOSTDOUT
#define CONFIG_SYS_WHITE_ON_BLACK
#define LCD_BPP LCD_COLOR16

#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE  (1366*767*4)
#define CONFIG_CMD_UNZIP
#define CONFIG_CMD_BMP
#define CONFIG_BMP_16BPP
#endif

在arch/arm/cpu/armv7/am33xx/clock_am33xx.c 中使能LCDC时钟.

&cmrtc->rtcclkctrl,
&cmper->usb0clkctrl,
&cmper->emiffwclkctrl,
&cmper->emifclkctrl,
&cmper->lcdclkctrl,
&cmper->lcdcclkstctrl,
&cmper->epwmss2clkctrl,
0

在 board.c 增加包括mmc, fat, lcd和帧缓冲区.

include <libfdt.h>
#include <fdt_support.h>
#include <mmc.h>
#include <fat.h>
#include <lcd.h>
#include <../../../drivers/video/am335x-fb.h>

这个示例代码是基于AM335x入门工具包的。GPIO控制背光,所以使用GPIO_TO_PIN来定义GPIO.

#define GPIO_ETH1_MODE          GPIO_TO_PIN(1, 26)

/* GPIO控制EVM-SK的背光*/
#define GPIO_BACKLIGHT_EN       GPIO_TO_PIN(3, 17)
在board_late_init中调用启动屏幕例程.
#if !defined(CONFIG_SPL_BUILD)
        splash_screen();
        /* try reading mac address from efuse */
        mac_lo = readl(&cdev->macid0l);
        mac_hi = readl(&cdev->macid0h);

下面的例程启用背光、加载LCD计时(本例基于Starter Kit)、打开LCD并启用它,最后是在mmc0上注册fat文件系统的启动屏幕代码。gzip的位图名为splash.bmp.gz,并通过bmp_display显示.

#if defined(CONFIG_LCD) && defined(CONFIG_AM335X_LCD) && \
                !defined(CONFIG_SPL_BUILD)
void lcdbacklight(int on)
{
        gpio_request(GPIO_BACKLIGHT_EN, "backlight_en");
        if (on)
                gpio_direction_output(GPIO_BACKLIGHT_EN, 0);
        else
                gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
}

int  load_lcdtiming(struct am335x_lcdpanel *panel)
{
        struct am335x_lcdpanel pnltmp;

        pnltmp.hactive = 480;
        pnltmp.vactive = 272;
        pnltmp.bpp = 16;
        pnltmp.hfp = 8;
        pnltmp.hbp = 43;
        pnltmp.hsw = 4;
        pnltmp.vfp = 4;
        pnltmp.vbp = 12;
        pnltmp.vsw = 10;
        pnltmp.pxl_clk_div = 2;
        pnltmp.pol = 0;
        pnltmp.pup_delay = 1;
        pnltmp.pon_delay = 1;
        panel_info.vl_rot = 0;

        memcpy((void *)panel, (void *)&pnltmp, sizeof(struct am335x_lcdpanel));

        return 0;
}

void lcdpower(int on)
{
        lcd_enable();
}

vidinfo_t       panel_info = {
                .vl_col = 480,
                .vl_row = 272,
                .vl_bpix = 4,
                .priv = 0
};

void lcd_ctrl_init(void *lcdbase)
{
        struct am335x_lcdpanel lcd_panel;

        memset(&lcd_panel, 0, sizeof(struct am335x_lcdpanel));
        if (load_lcdtiming(&lcd_panel) != 0)
                return;

        lcd_panel.panel_power_ctrl = &lcdpower;

        if (am335xfb_init(&lcd_panel) != 0)
                printf("ERROR: failed to initialize video!");

        /* Modify panel into to real resolution */
        panel_info.vl_col = lcd_panel.hactive;
        panel_info.vl_row = lcd_panel.vactive;

//      lcd_set_flush_dcache(1);
}

void lcd_enable(void)
{
        lcdbacklight(1);
}

void splash_screen(void)
{
        struct mmc      *mmc = NULL;
        int             err;

        mmc = find_mmc_device(0);
        if (!mmc)
                printf("Error finding mmc device\n");

        mmc_init(mmc);

        err = fat_register_device(&mmc->block_dev,
                                        CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);

        if (!err) {
                err = file_fat_read("splash.bmp.gz", (void *)0x82000000, 0);
                bmp_display(0x82000000, 0, 0);
        }
}
#endif
在 mux.c 定义LCDC pin mux.
#ifdef CONFIG_AM335X_LCD
static struct module_pin_mux lcd_pin_mux[] = {
        {OFFSET(lcd_data0), (MODE(0) | PULLUDDIS)},     /* LCD-Data(0) */
        {OFFSET(lcd_data1), (MODE(0) | PULLUDDIS)},     /* LCD-Data(1) */
        {OFFSET(lcd_data2), (MODE(0) | PULLUDDIS)},     /* LCD-Data(2) */
        {OFFSET(lcd_data3), (MODE(0) | PULLUDDIS)},     /* LCD-Data(3) */
        {OFFSET(lcd_data4), (MODE(0) | PULLUDDIS)},     /* LCD-Data(4) */
        {OFFSET(lcd_data5), (MODE(0) | PULLUDDIS)},     /* LCD-Data(5) */
        {OFFSET(lcd_data6), (MODE(0) | PULLUDDIS)},     /* LCD-Data(6) */
        {OFFSET(lcd_data7), (MODE(0) | PULLUDDIS)},     /* LCD-Data(7) */
        {OFFSET(lcd_data8), (MODE(0) | PULLUDDIS)},     /* LCD-Data(8) */
        {OFFSET(lcd_data9), (MODE(0) | PULLUDDIS)},     /* LCD-Data(9) */
        {OFFSET(lcd_data10), (MODE(0) | PULLUDDIS)},    /* LCD-Data(10) */
        {OFFSET(lcd_data11), (MODE(0) | PULLUDDIS)},    /* LCD-Data(11) */
        {OFFSET(lcd_data12), (MODE(0) | PULLUDDIS)},    /* LCD-Data(12) */
        {OFFSET(lcd_data13), (MODE(0) | PULLUDDIS)},    /* LCD-Data(13) */
        {OFFSET(lcd_data14), (MODE(0) | PULLUDDIS)},    /* LCD-Data(14) */
        {OFFSET(lcd_data15), (MODE(0) | PULLUDDIS)},    /* LCD-Data(15) */
        {OFFSET(gpmc_ad8), (MODE(1) | PULLUDDIS)},      /* LCD-Data(16) */
        {OFFSET(gpmc_ad9), (MODE(1) | PULLUDDIS)},      /* LCD-Data(17) */
        {OFFSET(gpmc_ad10), (MODE(1) | PULLUDDIS)},     /* LCD-Data(18) */
        {OFFSET(gpmc_ad11), (MODE(1) | PULLUDDIS)},     /* LCD-Data(19) */
        {OFFSET(gpmc_ad12), (MODE(1) | PULLUDDIS)},     /* LCD-Data(20) */
        {OFFSET(gpmc_ad13), (MODE(1) | PULLUDDIS)},     /* LCD-Data(21) */
        {OFFSET(gpmc_ad14), (MODE(1) | PULLUDDIS)},     /* LCD-Data(22) */
        {OFFSET(gpmc_ad15), (MODE(1) | PULLUDDIS)},     /* LCD-Data(23) */
        {OFFSET(lcd_vsync), (MODE(0) | PULLUDDIS)},     /* LCD-VSync */
        {OFFSET(lcd_hsync), (MODE(0) | PULLUDDIS)},     /* LCD-HSync */
        {OFFSET(lcd_ac_bias_en), (MODE(0) | PULLUDDIS)},/* LCD-DE */
        {OFFSET(lcd_pclk), (MODE(0) | PULLUDDIS)},      /* LCD-CLK */

        /* backlight */
        {OFFSET(mcasp0_ahclkr), (MODE(7) | PULLUDDIS)}, /* mcasp0_gpio */

        {-1},
};
#endif
And enable the LCD.
        } else if (board_is_evm_sk()) {
                /* Starter Kit EVM */
                configure_module_pin_mux(i2c1_pin_mux);
                configure_module_pin_mux(gpio0_7_pin_mux);
                configure_module_pin_mux(rgmii1_pin_mux);
                configure_module_pin_mux(mmc0_pin_mux_sk_evm);
#ifdef CONFIG_AM335X_LCD
                configure_module_pin_mux(lcd_pin_mux);
#endif
        } else if (board_is_bone_lt()) {

3.1.4. 故障排除
1.U-boot升级后,内核停止引导
检查下列情况之一是否适用:
•U-boot版本升级/降级后,不重置U-boot环境变量
从一个版本到另一个版本,u-boot的一些环境变量可能会改变。升级/降级u-boot版本时,需要对u-boot环境变量进行重置,以保证环境变量与所使用的版本正确匹配。当启动不同版本的u-boot时,可以通过按任意键来中断u-boot的启动过程,以获得u-boot提示符。此时,需要执行以下命令重置u-boot环境变量。

# env default -f -a
# saveenv

•混合匹配U-boot和Linux内核版本
有时用户会混合使用不同SDK版本的u-boot和内核版本。在大多数情况下这可能是好的,但是TI建议u-boot和内核来自同一个SDK版本。从一个版本到另一个版本,u-boot环境变量可能会发生变化,包括加载地址、内核映像格式等。u-boot和内核之间这些变化的任何不兼容性都会导致引导问题。因此,在升级或降级u-boot时,需要重置u-boot环境变量。请参阅上一个项目符号中的如何重置u-boot环境变量。
2.无法使用不同的启动模式启动U-boot
•检查是否遵循支持的u-boot引导模式的说明。
请遵循U-boot用户指南中的说明
不同的启动模式使用不同的映像格式。他们是:.
• u-boot-spi.gph
• rootfs-image.ubi
• u-boot.bin
• MLO

上一篇:VK1072B 2.4V~5.2V 驱动18SEG×4COM点阵 1/2, 1/3偏压 用于液晶LCD显示驱动IC


下一篇:基于51单片机的智能孵化器恒温箱 原理图PCB程序设计