U-Boot supports serial NOR flashes which hook up to the Blackfin processor via a 4 wire SPI-compatible interface. Commands are provided for reading/erasing/writing of the device.
In terms of the command line interface, the
sf command is the interface to all serial flash operations. It allows you to read/erase/write a sequential range of bytes as well as query the SPI flash. You can also select different flashes at runtime based on the SPI chip select.
In terms of U-Boot code, U-Boot provides a SPI flash framework while the Blackfin port provides a driver for the on-chip SPI controller. Every SPI flash type has its own specific subdriver which can be found in the
drivers/mtd/spi/ directory. If the SPI flash you want to use is not supported, you'll have to implement your own subdriver. See the supported flashes section for more information.
sfinterface which was introduced with 2009R1 / u-boot-2008.10+. If you're using an older release, please see the
There is no limit in terms of flash sizes that the SPI interface can support. U-Boot can work with the SPI flash regardless of its size. The current largest is about 128 megabits / 16 megabytes and it works great!
Every SPI flash vendor likes to implement their own command interface with their own extensions. When selecting a SPI flash for your board, you should first make sure it supports the JEDEC identification standard. Everything made recently should comply, but double check the datasheet.
The specific list of parts that are currently supported:
|Atmel||AT45DB011D AT45DB021D AT45DB041D AT45DB081D AT45DB161D AT45DB321D AT45DB642D|
|Macronix||MX25L1605D MX25L3205D MX25L6405D MX25L12805D MX25L12855E|
|Spansion||S25FL008A S25FL016A S25FL032A S25FL064A S25FL128P|
|SST||SST25VF040B SST25VF080B SST25VF016B SST25VF032B SST25WF512 SST25WF010 SST25WF020 SST25WF040|
|ST Micro||M25P16 M25P20 M25P32 M25P40 M25P64 M25P80 M25P128|
|Winbond||W25X16 W25X32 W25X64|
You will need these defined in your board configuration file in order to enable support for serial flashes.
If you want to store the U-Boot environment in SPI flash, then use these defines.
Then you should define these according to the parts you have.
At runtime, you can detect any SPI flash to make sure things are detected properly. This command must be run first before doing any other SPI flash operation.
bfin> sf probe 2 SF: Got idcode 20 20 15 2048 KiB M25P16 at 0:2 is now current device
Here we can see that there is a 16 megabit ST Micro flash hooked up. Good times.
You use the
sf read command to read a range of bytes from the serial flash into memory. From there, you can do anything you like with it. For example, if we want to read 0x1000 bytes at an offset of 0x300 bytes from the start of the serial flash into external memory at 0x2000000, we'd simply run:
bfin> sf read 0x2000000 0x300 0x1000 bfin> md.b 0x2000000 02000000: 4a e1 c0 ff 10 62 0a e1 04 0a 40 e1 c2 ff 10 93 J....b....@..... 02000010: 22 6c 10 93 48 60 c2 6f 10 97 4a e1 e0 ff 20 e1 "l..H`.o..J... . 02000020: fd 01 0a e1 04 20 88 4f 10 93 c6 6c 27 01 30 05 ..... .O...l'.0. 02000030: 10 00 00 00 4a e1 e0 ff 40 e1 fa 03 0a e1 0c 20 ....J...@......
Again, you do not need to worry about how the serial flash is split up into pages, so you could just as easily read multiple pages/sectors/blocks/whatever with one command.
You use the
sf erase command to erase pages/sectors of the serial flash. Like any normal flash system, you must erase things before you can write to them, and you must erase on sector boundaries.
For example, if we want to erase the sector starting at 0x30000, then we'd do:
bfin> sf erase 0x30000 0x10000
Here the sector size is 0x10000 bytes.
You use the
sf write command to write a range of bytes from memory into some offset into the serial flash. For example, if we want to write 0x100000 bytes from external memory at 0x20000000 into the serial flash at an offset of 0x0 bytes, we'd simply run:
bfin> sf write 0x20000000 0x0 0x100000
There is no need for you to worry about writing out only a page of data at a time.
When most people talk about booting, they sometimes forget that there are two aspects of booting a system - chip and hardware initialization (done by the bootloader), and booting the kernel.
This is covered in the booting_methods section.
This is a simple matter of loading a uImage from SPI flash (via chip select 2), and doing a
bootm command on it. For example the following
bfin> set sfboot 'sf probe 2; sf read 0x2000000 0x300 0x100000; bootm 0x2000000' bfin> set bootcmd run sfboot bfin> save
The next time this board boots, it will run the
sfboot command, which probes the flash at CS
2, loads the image located in offset
0x300, with a length of
0x100000, into memory location
0x2000000, and then does a bootm on it. Simple!