U-Boot is able to utilize parallel NOR flash hooked up to the Blackfin processor's asynchronous memory banks. Commands are provided for common flash operations such as:
If the flash is CFI compliant, then common U-Boot code can handle detection of the flash automatically given a few board-specific defines (such as the location of the flash in the processor's address space).
If the flash is not CFI compliant, then you will need to write a board-specific driver. Doing so is beyond the scope of this documentation. Instead of wasting software development time, stop being cheap and just buy a CFI compliant flash.
Keep in mind that the size of the flash is limited to the asynchronous memory bank range which differs according to the processor variant. Some Blackfin processors can only support up to 4 megabytes while others can support up to 32 megabytes. Consult the datasheet for your variant for more information.
For CFI compliant flashes, you simply need the following defines in your board header file.
/* Board independent required settings */ #define CONFIG_SYS_FLASH_CFI /* Flash is CFI compliant */ #define CONFIG_FLASH_CFI_DRIVER /* Use the common CFI flash driver */ /* Board dependent required settings */ #define CONFIGS_SYS_FLASH_BASE 0x20000000 /* Address flash is mapped */ /* Max number of banks -- can be greater than available, but cannot be smaller */ #define CONFIG_SYS_MAX_FLASH_BANKS 1 /* Max number of sectors -- can be greater than available, but cannot be smaller */ #define CONFIG_SYS_MAX_FLASH_SECT 71 /* Optional settings */ #define CONFIG_SYS_FLASH_PROTECTION 1 /* Use hardware flash protection */
For more information, see the top level U-Boot README file.
Once U-Boot is running, you can query the flash information to make sure things are kosher. For example, the output on a BF537-STAMP board looks something like:
bfin> flinfo Bank # 1: CFI conformant FLASH (16 x 16) Size: 4 MB in 71 Sectors Erase timeout 8192 ms, write timeout 1 ms, buffer write timeout 1 ms, buffer size 1 Sector Start Addresses: 20000000 (RO) 20002000 (RO) 20004000 (RO) 20006000 (RO) 20008000 (RO) 2000A000 (RO) 2000C000 (RO) 2000E000 (RO) 20010000 (RO) 20020000 20030000 20040000 20050000 20060000 20070000 20080000 20090000 200A0000 200B0000 200C0000 200D0000 200E0000 200F0000 20100000 20110000 20120000 20130000 20140000 20150000 20160000 20170000 20180000 20190000 201A0000 201B0000 201C0000 201D0000 201E0000 201F0000 20200000 20210000 20220000 20230000 20240000 20250000 20260000 20270000 20280000 20290000 202A0000 202B0000 202C0000 202D0000 202E0000 202F0000 20300000 20310000 20320000 20330000 20340000 20350000 20360000 20370000 20380000 20390000 203A0000 203B0000 203C0000 203D0000 203E0000 203F0000 (RO)
Here we can see a bottom boot 4 megabyte CFI compliant flash with 71 sectors.
The address of every sector found is displayed for easy reference. Any sector with
(RO) after it means that U-Boot will prevent writing of the sector (see protection below for more information).
U-Boot offers write protection (in hardware or software) on a per-sector level for parallel flashes. Access to this protection is via the aptly named
bfin> help protect protect on start end - protect FLASH from addr 'start' to addr 'end' protect on start +len - protect FLASH from addr 'start' to end of sect w/addr 'start'+'len'-1 protect on N:SF[-SL] - protect sectors SF-SL in FLASH bank # N protect on bank N - protect FLASH bank # N protect on all - protect all FLASH banks protect off start end - make FLASH from addr 'start' to addr 'end' writable protect off start +len - make FLASH from addr 'start' to end of sect w/addr 'start'+'len'-1 wrtable protect off N:SF[-SL] - make sectors SF-SL writable in FLASH bank # N protect off bank N - make FLASH bank # N writable protect off all - make all FLASH banks writable
By default, the Blackfin boards will set all the sectors that U-Boot itself lives in as read-only. You can of course control this behavior in your board-specific code.
For the lazy, you can make all sectors writable by simply using the
protect off all command.
bfin> protect off all Un-Protect Flash Bank # 1 ....................................................................... done
Access to parallel flash is done via the standard U-Boot memory functions. That means you can simply read parallel flash directly like any other external memory location.
bfin> md.b 0x20000000 0x20 20000000: 0e e1 00 10 4e e1 b0 ff 90 61 10 3e 01 60 21 36 ....N....a.>.`!6 20000010: 29 36 31 36 39 36 01 3c 19 3c fc 31 00 e3 56 00 )61696.<.<.1..V. bfin> cp.b 0x20000000 0 0x20 bfin> md.b 0 0x20 00000000: 0e e1 00 10 4e e1 b0 ff 90 61 10 3e 01 60 21 36 ....N....a.>.`!6 00000010: 29 36 31 36 39 36 01 3c 19 3c fc 31 00 e3 56 00 )61696.<.<.1..V.
Reading can be done at any offset independent of sector.
Due to the nature of flash technology, you obviously need to erase things before you can write them out. This is accomplished via the
erase command and, again due to the nature of flash, must be done on sector boundaries.
bfin> help erase erase start end - erase FLASH from addr 'start' to addr 'end' erase start +len - erase FLASH from addr 'start' to the end of sect w/addr 'start'+'len'-1 erase N:SF[-SL] - erase sectors SF-SL in FLASH bank # N erase bank N - erase FLASH bank # N erase all - erase all FLASH banks
So to refer to the previous BF537-STAMP example, if we wish to erase a few sectors in the middle of the flash, we'd simply use a command like so:
bfin> erase 0x201C0000 0x2026FFFF ........... done Erased 11 sectors
Notice that in the sector output from the
flinfo command, the sector start addresses are shown. However, the
end address is inclusive in the erased range, so we need to give the address of the first sector we don't want erased and subtract one from it.
Once again, due to the nature of flash technology, bits can written from 1 to 0 but not back again. Writes can also be done at the byte level rather than sector level. However, if you wish to change a 0 to a 1, you need to erase the sectors in question first.
To write flash, you need to use the
cp U-Boot command. Load whatever data you wish to write to flash into some memory location (commonly via TFTP), and then copy it from that memory location into flash. Here we assume the sectors in question have already been erased and so we'll simply fill external memory with random bytes and then copy them into the flash.
bfin> md.b 0x201c0000 201c0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 201c0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ bfin> mw.b 0 0xee 0x20 bfin> md.b 0 00000000: ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ................ 00000010: ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ................ bfin> cp.b 0 0x201c0000 10 Copy to Flash... done bfin> md.b 0x201c0000 201c0000: ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ................ 201c0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
After writing, you can/should verify that the write was completed properly with the
cmp (compare) command
bfin> help cmp cmp - memory compare Usage: cmp [.b, .w, .l] addr1 addr2 count bfin> cmp.b 0 0x201c0000 10 Total of 16 bytes were the same
Conversely, your board may not have any parallel flash at all so you want to disable support for it. Here are the things you need in your board configuration file.