This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Contents[hide]
|
In AM335x the ROM code serves as the 1st stage bootloader. The 2nd and the 3rd stage bootloaders are based on U-Boot. In the rest of this document when referring to the binaries, the binary for the 2nd stage is referred to as SPL and the binary for the 3rd stage as simply U-Boot. SPL is a non-interactive loader and is a specially built version of U-Boot. It is built concurrently when building U-Boot.
The ROM code can load the SPL image from any of the following devices
在AM335X的只读存储器的程序提供第一个阶段的引导,而第二个阶段和第三个阶段的引导程序必须是在U-Boot上面,在本文的其余部分,当提及到二进制文件的时候,第二个阶段的二进制文件是与spl相关的,而第三个阶段的二进制文件就是雨U-boot相关。SPL是一个没有相关性的加载器和一个特定版本的U-Boot。它协调得的编译当编译U-Boot的时候。
Memory devices non XIP (NAND/SDMMC)
The image should have the Image header. The image header is of length 8 byte which has the load address(Entry point) and the size of the image to be copied. RBL would copy the image, whose size is given by the length field in the image header, from the device and loads into the internal memory address specified in the load address field of Image header.
RBL loads the image to the internal memory address 0x402f0400 and executes it. No Image Header present.
This section gives an overview of the two stage U-Boot approach adopted for AM335X.
The size of the internal RAM in AM335X is 128KB out of which 18KB at the end is used by the ROM code. Also, 1 KB at the start (0x402f0000 - 0x402f0400) is secure and it cannot be accessed This places a limit of 109KB on the size of the U-Boot binary which the ROM code can transfer to the internal RAM and use as an initial stack before initialization of DRAM.
Since it is not possible to squeeze in all the functionality that is normally expected from U-Boot in < 110KB (after setting aside some space for stack, heap etc) a two stage approach has been adopted. Initial stage initalize only the required boot devices (NAND, MMC, I@C etc)& 2nd full stage initall all other devices (ethernet, timers, clocks etc). The 1st binary is generated MLO and the 2nd stage is generated as u-boot.img.
由于,它没有必要压榨在所有的机能,平常得期望U-Boot是控制在110KB(通过节省一些堆栈的空间),所以两个阶段的方式就被采取了。在初始化阶段,初始化的仅仅是一个需要启动的设备,如NAND,MMC,I2C 等等,在全部阶段将初始化所有的其他设备包括网络,定时器,时钟等等。第一个阶段产生MLO而第二个阶段产生U-BOOT.IMG
Note
Using GNU toolchain for ARM processors from Arago is recommended. Arago Toolchain is available as an Ubuntu executable here
Assuming the release package is extracted inside directory represented as $AM335x-PSP-DIR:
$ cd $AM335x-PSP-DIR/AM335x-LINUX-PSP-MM.mm.pp.bb/src/u-boot $ tar -xvzf u-boot-MM.mm.pp.bb.tar.gz
Change to the base of the U-Boot directory.
$ cd ./AM335x-LINUX-PSP-MM.mm.pp.bb/src/u-boot/u-boot-MM.mm.pp.bb
Building into a separate object directory with the "O=" parameter to make is strongly recommended.
$ rm -rf ./am335x $ make O=am335x CROSS_COMPILE=arm-arago-linux-gnueabi- ARCH=arm am335x_evm
This will generate two binaries in the am335x directory, MLO and u-boot.img along with other intermediate binaries that may be needed in some cases (see below).
Connect a serial cable from the serial port of the EVM (serial port is next to the power switch) to the COM port on either the Windows machine or Linux host depending on where you'll be running the serial terminal software.
For correct operation the serial terminal software should be configured with the following settings:
If Teraterm is being used ensure that the latest version (4.67) of Teraterm is installed. The implementation of the kermit protocol in Teraterm is not reliable in older versions. The latest version of Teraterm 4.67 can be downloaded from here Recent Teraterm updates causes slow Binary transfer over UART. In such cases use, Windows in-built HyperTerminal application.
Switch SW3 is for selecting the boot modes and device selection depends on the DIP switches intended for profile selection on EVMs.
The picture below shows the boot mode configuration switch SW3 on the AM335X EVM.
Note
RED: circle shows OFF and GREEN circles shows ON switches.
Note
Switch SW3, SW3[5:1] ==> 10010 , other pins should be 0 (i.e. OFF). This sets the Boot mode pins (BTM[4:0]) to NAND boot mode
Note
Switch SW3, SW3[5:1] ==> 10110 , other pins should be 0 (i.e. OFF). This Boot mode pins (BTM[4:0]) to SPI boot mode
Note
Switch SW3, SW3[5:1] ==> 00001 , other pins should be 0 (i.e. OFF). This Boot mode pins (BTM[4:0]) to UART boot mode
Switch SW3, SW3[5:1] ==> 10111 , other pins should be 0 (i.e. OFF). This Boot mode pins (BTM[4:0]) to SD boot mode.
Note
You can flash the SPL & U-Boot onto NAND (for NAND boot) using the Flashing Tools provided in the PSP releases.
Refer to AM335x Flashing Tools Guide wiki page for instructions on how to flash the pre-built (or compiled) binary to NAND flash (or the recompiled one) with the help of the NAND flash writer.
After flashing the 2 stages use the appropriate switch settings to boot from NAND .
Note
It is possible to flash U-Boot to NAND from the 2nd stage of U-Boot which is loaded over UART or from SD card or previously flashed into NAND. Before proceeding with this please make sure that the 2 binaries for flashing (SPL and U-Boot) have been built.
Make sure the two binaries for NAND boot (SPL and U-Boot) which are required for flashing are present on the SD. Please refer to the section of building U-Boot to generate the images.
Note
This section gives an overview of the NAND support in U-Boot. It also describe how to store the kernel image, RAMDISK or the UBIFS filesystem to NAND so as to have a network-free boot right from powering on the board to getting the kernel up and running.
Micron Nand parts (page size 2KB, block size 128KB) are supported on AM335XEVM platforms.
Note
The NAND part on the EVM has been configured in the following manner. The addresses mentioned here are used in the subsequent NAND related commands.
+------------+-->0x00000000-> SPL start (SPL copy on 1st block) | | | |-->0x0001FFFF-> SPL end | |-->0x00020000-> SPL.backup1 start (SPL copy on 2nd block) | | | |-->0x0003FFFF-> SPL.backup1 end | |-->0x00040000-> SPL.backup2 start (SPL copy on 3rd block) | | | |-->0x0005FFFF-> SPL.backup2 end | |-->0x00060000-> SPL.backup3 start (SPL copy on 4th block) | | | |-->0x0007FFFF-> SPL.backup3 end | |-->0x00080000-> U-Boot start | | | |-->0x002BFFFF-> U-Boot end | |-->0x00260000-> ENV start | | | | | |-->0x0027FFFF-> ENV end | |-->0x00280000-> Linux Kernel start | | | | | | | | | |-->0x0077FFFF-> Linux Kernel end | |-->0x00780000-> File system start | | | | | | | | | | | | | | | | | | | | | | | | +------------+-->0x10000000-> NAND end (Free end)
To write len bytes of data from a memory buffer located at addr to the NAND block offset:
U-Boot# nand write <addr> <offset> <len>
Note
If a bad block is encountered during the write operation, it is skipped and the write operation continues from next 'good' block.
For example, to write 0x40000 bytes from memory buffer at address 0x80000000 to NAND - starting at block 32 (offset 0x400000):
U-Boot# nand write 0x80000000 0x400000 0x40000
To read len bytes of data from NAND block at a particular offset to the memory buffer in DDR located at addr:
U-Boot# nand read <addr> <offset> <len>
If a bad block is encountered during the read operation, it is skipped and the read operation continues from next 'good' block.
For example, to read 0x40000 bytes from NAND - starting at block 32 (offset 0x400000) to memory buffer at address 0x80000000:
U-Boot# nand read 0x80000000 0x400000 0x40000
Some of the blocks in the NAND may get corrupted over a period of time. In such cases you should explicitly mark such blocks as bad so that the image that you are writing to NAND does not end up getting corrupted.
To forcefully mark a block as bad:
U-Boot# nand markbad <offset>
For example, to mark block 32 (assuming erase block size of 128Kbytes) as bad block - offset = blocknum * 128 * 1024:
U-Boot# nand markbad 0x400000
To view the list of bad blocks:
U-Boot# nand bad
Note
To erase NAND blocks in a particular the address range or using block numbers:
U-Boot# nand erase <start offset addr> <len>
Note
This commands skips bad blocks (both factory and user marked) encountered within the specified range.
For example, to erase blocks 32 through 34:
U-Boot# nand erase 0x00400000 0x40000
NAND flash memory, although cheap, suffers from problems like bit flipping which lead to data corruption. However by making use of some error correction coding (ECC) techniques it is possible to work around this problem.
For the data stored in NAND flash, U-Boot supports following NAND ECC schemes
Current releases do not support BCH4.
For any ECC scheme we need to add some extra data while writing so as to detect and correct (if possible) the errors introduced by the NAND part. In case of BCH scheme some bytes are needed to store the ECC related info.
The section of NAND memory where addition info like ECC data is stored is referred to as Out Of Band or OOB section.
The first 2 bytes are used for Bad block marker – 0xFFFF => Good block
The next ‘N’ bytes is used for BCH bytes
N = B * <Number of 512-byte sectors in a page>
So for a 2k page-size NAND flash with 64-byte OOB size, we will use BCH8. This will consume 2 + (14*4) = 58 bytes out of 64 bytes available.
The NAND flash part used in EVM does not have enough spare area to support BCH16.
ECC type | Usage |
---|---|
S/W ECC | Not used |
H/W ECC - Hamming Code | Should use this scheme only for flashing the U-Boot ENV variables. |
H/W ECC – BCH8 | Should use this scheme while flashing any image/binary other than the U-Boot ENV variables. |
To select ECC algorithm for NAND:
U-Boot# nandecc [sw | hw <hw_type>]
Usage:
sw - Set software ECC for NAND hw <hw_type> - Set hardware ECC for NAND <hw_type> - 0 for Hamming code 1 for bch4 2 for bch8 3 for bch16 Currently we support only Software, Hamming Code and BCH8. We do not support BCH4 and BCH16
Component | Default ECC scheme used by the component | ECC scheme to be used to flash the component | ECC schemes supported by the component |
---|---|---|---|
SPL | BCH8 | BCH8 | BCH8 |
U-boot | Hamming | BCH8 | Hamming/BCH8 |
Linux | BCH8 | BCH8 | BCH8 |
File System | NA | BCH8 | NA |
Environment variables | NA | Hamming | NA |
TFTP the kernel uImage to DDR.
U-Boot# mw.b 0x82000000 0xff 0x500000 U-Boot# tftp 0x82000000 <kernel_image>
Now flash the kernel image to NAND at the appropriate offset (refer to NAND layout section for the offsets)
U-Boot# nandecc hw 2 U-Boot# nand erase 0x00280000 0x00500000 U-Boot# nand write 0x82000000 0x00280000 0x500000
Note
In AM335X, UBIFS file system is used in NAND flash as it is next generation flash file system.
1. creating of UBIFS file system image is described over here
2. Follow the steps mentioned below to Flash UBIFS image
Note: In case of AM335x, file system partition is starting from 0x780000. So from U-Boot, flashing offset for file system from U-Boot is 0x780000 and from Linux MTD partition number 7 should used for flashing file file system.
Get the UBIFS image to U-Boot from tftp or MMC/SD or UART. Lets consider an example of MMC card.
Since we copy the data to NAND, Empty/Erase the required RAM. Then, get the UBIFS image to U-Boot
Load the memory with 0xFF
u-boot# mw.b 0x82000000 0xFF <filesystem_image_size>
filesystem image size is upward aligned to NAND page size.
Load the UBIFS file system image, in the example below from MMC as
u-boot# mmc rescan u-boot# fatload mmc 0 0x82000000 ubi.img
Erase the NAND. Switch to BCH8 ECC and the flash the image assuming NAND partition to be erased starts from "0x780000" and is of size "0xF880000". File system size to be flashed is 0xFC0000 which is upward aligned to NAND block size.
u-boot# nand erase 0x00780000 0xF880000 u-boot# nandecc hw 2 u-boot# nand write 0x82000000 0x780000 0xFC0000
ubiformat /dev/mtd<X> -f ubi.img -s 512 -O 2048
Assuming 7th mtd partition, we can use the following command to flash the ubifs image to partition 7.
#ubiformat /dev/mtd7 -f ubi.img -s 512 -O 2048
NOT SUPPORTED IN THIS RELEASE
NOT SUPPORTED IN THIS RELEASE
This section describes how to use UART boot mode using TeraTerm.
Note
Before proceeding with any of the commands given in this section please make sure that profile is selected to enable NAND on the EVM. The switch for selecting profile for NAND is described here.
Boot using UART boot mode as here
After the U-Boot prompt U-Boot# comes up, the images for the 1st stage and 2nd stage can be flashed to NAND for persistent storage.
Flash SPL (MLO) to NAND by executing the following commands:
U-Boot# mw.b 0x82000000 0xFF 0x20000 U-Boot# loadb 0x82000000
U-Boot# nand erase 0x0 0x20000 U-Boot# nandecc hw 2 U-Boot# nand write.i 0x82000000 0x0 0x20000
If no error messages are displayed the SPL of NAND boot has been successfully transferred to NAND.
Flash the 2nd stage U-Boot (u-boot.img) to NAND by executing the following commands:
U-Boot# mw.b 0x82000000 0xFF 0x40000 U-Boot# loadb 0x82000000
U-Boot# nand erase 0x80000 0x40000 U-Boot# nandecc hw 2 U-Boot# nand write.i 0x82000000 0x80000 0x40000
If no error messages are displayed the U-boot of NAND boot has been successfully transferred to NAND.
This section gives an overview of the SD (Secured Digital Card) support in U-Boot
SD (Secured Digital Card) support is available through HSMMC controller.
SD support is available by default in all U-Boot configs. SD card can be accessed in all other boot modes (NAND/SPI).
Please note that the following commands are being executed from the 2nd stage. List files on a FAT32 formatted SD card
U-Boot# mmc rescan U-Boot# fatls mmc 0
Booting kernel image from the SD card
U-Boot# mmc rescan U-Boot# fatload mmc 0 0x82000000 uImage U-Boot# bootm 0x82000000
Booting application (ex. u-boot.img) image from the SD card
U-Boot# mmc rescan U-Boot# fatload mmc 0 0x82000000 u-boot.img U-Boot# go 0x82000000
This section describes steps to be followed to create a standalone power-on bootable system on SD card.
Prerequisites Ensure that following is available:
Note
Steps
./mksd-am335x.sh <sd-device-name> <sd-1st-stage-bootloader> <sd-2nd-stage-bootloader> <kernel-uImage> <filesystem>
sudo ./mksd-am335x.sh /dev/sdd MLO u-boot.img uImage nfs.tar.gz
Once the SD card has been setup as described in the previous section make sure the switch setting are set for SD boot mode and then plug in the SD card in the MMC/SD card slot on the EVM.
Before proceeding with any of the commands given in this section please make sure that profile is selected to enable NAND on the EVM. The switch for selecting profile for NAND is described here.
Boot using SD boot mode as here
After the 2nd stage prompt U-Boot# comes up, the images for the 1st stage and 2nd stage can be flashed to NAND for persistent storage.
Flash SPL (MLO) to NAND by executing the following commands:
U-Boot# mmc rescan U-Boot# mw.b 0x82000000 0xFF 0x20000 U-Boot# fatload mmc 0 0x82000000 MLO U-Boot# nandecc hw 2 U-Boot# nand erase 0x0 0x20000 U-Boot# nand write.i 0x82000000 0x0 0x20000
If no error messages are displayed the SPL of NAND boot has been successfully transferred to NAND.
Flash the 2nd stage U-Boot (u-boot.img) to NAND by executing the following commands:
U-Boot# mmc rescan U-Boot# mw.b 0x82000000 0xFF 0x40000 U-Boot# fatload mmc 0 0x82000000 u-boot.img U-Boot# nandecc hw 2 U-Boot# nand erase 0x80000 0x40000 U-Boot# nand write.i 0x82000000 0x80000 0x40000
If no error messages are displayed the U-boot of NAND boot has been successfully transferred to NAND.
U-Boot environment variables can be modified using a plain text file named uEnv.txt. The scripts can be used to modify and even over-ride the various parameters like bootargs, TFTP serverip etc. If a command named uenvcmd is defined in the file it will be executed.
Example text file named uEnv.txt
IMPORTANT
bootargs=console=ttyO0,115200n8 root=/dev/mmcblk0p2 mem=128M rootwait bootcmd=mmc rescan; fatload mmc 0 0x82000000 uImage; bootm 0x82000000 uenvcmd=boot
The file uEnv.txt is automatically loaded from MMC if the bootcmd is run. It can be loaded and put into the environment manually, for example TFTP the file to some location in DDR and then use the following commands (assumption: network setting has already been done using the steps mentioned in this User Guide)
U-Boot# tftp 0x82000000 uEnv.txt
... Make note of the number of bytes downloaded ...
U-Boot# env import -t 0x82000000 number_of_bytes_above
The file can even be placed in the SD card and then bootcmd set to autorun this script if present.
uEnv.txt on an SD card can be used to override the env settings saved on a persistent storage like NAND by making use of the following commands
U-Boot# mmc rescan U-Boot# fatload mmc 0 0x81000000 uEnv.txt U-Boot# env import -t 0x81000000 $filesize U-Boot# boot
In order to download the Linux kernel image from the TFTP server and for mounting NFS the network settings in U-Boot need to be configured.
Note
When booting for the first time, U-Boot tries to fetch the MAC address from the env space. If it returns empty, it will look for MAC address from the eFuse registers in the Control module space and set the "ethaddr" variable in the env appropriately. The ethaddr can also be set using the setenv/saveenv commands. In such cases the user-set MAC address will take effect on subsequent reboot only.
To set a different MAC address use the following command
U-Boot# set ethaddr <random MAC address eg- 08:11:23:32:12:77>
Note
In case a static ip is not available run the dhcp command to obtain the ip address from the DHCP server on the network to which the EVM is connected.
U-Boot# setenv serverip <tftp server in your network> U-Boot# netmask 255.255.255.0 U-Boot# dhcp U-Boot# saveenv
In case a static ip is available run the following commands
U-Boot# setenv ipaddr <your static ip> U-Boot# saveenv
This completes the network configuration in U-Boot.
After completing the network configuration and flashing the kernel image and filesystems to flash you need to set some other parameters which are essential for booting the kernel. We make use of a number of existing helper variables that exist in the environment at present. To see what they are set to use the printenv command. After setting bootargs along with any other variables for your needs you will need to do:
U-Boot# saveenv
In all cases we make use of optargs to control passing in of additional arguments and ip_method to determine how the kernel will deal with networking PRIOR to userspace spawning init. This does not control for example if a dhcp client will be started as part of the userspace init sequence.
In case you are using a RAMDISK as the Linux filesystem:
U-Boot# setenv bootargs ${console} ${optargs} root=/dev/ram rw initrd=${loadaddr},32MB ip=${ip_method}
For booting from NAND:
U-Boot# setenv nand_src_addr 0x00280000 U-Boot# setenv nand_img_siz 0x170000 U-Boot# setenv initrd_src_addr 0x00780000 U-Boot# setenv initrd_img_siz 0x320000 U-Boot# setenv bootcmd 'nand read.i ${kloadaddr} ${nand_src_addr} ${nand_img_siz};nand read.i ${loadaddr} ${initrd_src_addr} ${initrd_img_siz};bootm ${kloadaddr}'
For booting from SD card:
U-Boot# setenv bootcmd 'mmc rescan;run mmc_load_uimage;fatload mmc ${mmc_dev} ${loadaddr} initrd.ext3.gz;bootm ${kloadaddr}'
Note
root=ubi0:<VOLUME NAME> ubi.mtd=<PARTITION_ID>,YYYY rw
The value of PARTITION_ID depends on MTD device which holds the rootfs, YYYY depends on the page size of the partition and VOLUME NAME depends on the volume name given in ubinize.cfg file while creating UBIFS image as described here . In cases where you have multiple UBI volumes, ubi0 would change to the volume with the root partition.
Once nand_root is set:
U-Boot# setenv bootcmd run nand_boot
Note
Modify the required variables:
U-Boot# print ethaddr <-- Check if MAC address is assigned and is unique U-Boot# setenv ethaddr <unique-MAC-address> <-- Set only if not present already, format uv:yy:zz:aa:bb:cc U-Boot# setenv serverip <NFS and TFTP server-ip> U-Boot# setenv rootpath /location/of/nfsroot/export U-Boot# setenv bootcmd net_boot
In case everything went well, boot the kernel from U-Boot using the following command.
U-Boot# boot