world leader in high performance signal processing
Trace: » serial-flash

Serial NOR Flash and U-Boot

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.

This page documents the sf interface which was introduced with 2009R1 / u-boot-2008.10+. If you're using an older release, please see the eeprom page: serial-flash-eeprom

Supported Flashes

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:

Vendor Parts
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

Configuration

You will need these defined in your board configuration file in order to enable support for serial flashes.

  • CONFIG_BFIN_SPI -- Blackfin on-chip SPI controller
  • CONFIG_SPI_FLASH -- SPI Flash subsystem
  • CONFIG_CMD_SF -- Command line interface sf
  • CONFIG_SF_DEFAULT_SPEED -- speed to run the SPI flash
  • CONFIG_SF_DEFAULT_MODE -- by default, SPI_MODE_3 is used (see spi for more info)

If you want to store the U-Boot environment in SPI flash, then use these defines.

  • CONFIG_ENV_IS_IN_SPI_FLASH -- store the env in SPI flash
  • CONFIG_ENV_SPI_MAX_HZ -- speed to run the SPI flash
  • CONFIG_ENV_SPI_MODE -- by default, SPI_MODE_3 is used (see spi for more info)
  • CONFIG_ENV_SPI_BUS -- by default, bus 0 is used
  • CONFIG_ENV_SPI_CS -- by default, the CS the bootrom uses

Then you should define these according to the parts you have.

  • CONFIG_SPI_FLASH_ATMEL
  • CONFIG_SPI_FLASH_MACRONIX
  • CONFIG_SPI_FLASH_SPANSION
  • CONFIG_SPI_FLASH_SST
  • CONFIG_SPI_FLASH_STMICRO
  • CONFIG_SPI_FLASH_WINBOND

Probing

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.

Reading

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.

Erasing

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.

Writing

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.

Booting

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.

Booting the Blackfin (U-Boot in SPI Flash)

This is covered in the booting_methods section.

Booting Linux (Linux in SPI Flash)

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!