Flashing Images (Naon)

From DAVE Developer's Wiki
Jump to: navigation, search
Info Box
Naon am387x-dm814x.png Applies to Naon
Maya 03.png Applies to Maya
Dido-main.png Applies to Dido
Tux.png Applies to U-Boot

Introduction

In this article we'll see in detail how to flash binaries images into Naon on-board flash memories.

Three kind of binaries are usually programmed on flash memory:

  1. U-Boot (1st and 2nd stage)
  2. Kernel
  3. root file system, which can be
    • ramdisk binary image
    • flash file system (e.g. JFFS2 or UBIFS) image/files

Flash devices are also called Memory Tecnology Device (MTD) in Linux kernel terms. Please also take a look at MTD article on this wiki for flash memories usage in Linux. In this article we'll take a look only at flash memories from U-Boot point of view.

We also assume that:

  • user have a valid U-Boot image flashed on the board with the required flash device support
  • user can load the image into ram via TFTP
    • there's also a serial load option (using kermit or ymodem protocol) but we'll take care of this (primary due its slowness). Anyway, you can refer to Recovery U-Boot Image (Naon) again, which uses the serial port to download the 2nd stage U-Boot binary.


Warning-icon.png Please note that loading the wrong U-Boot (1st or 2nd stage) image may damage the hardware permanently. Also a power interruption during the U-Boot update process may not allow the board to boot correctly. In this case user can refer to Recovery U-Boot Image (Naon) procedure for recovery Warning-icon.png


200px-Emblem-important.svg.png Please note that U-Boot 1st stage does NOT have networking support, due size constraint. For this reason, a corruption of the 2nd stage will allow 1st stage boot but will not allow loading 2nd stage via TFTP. Again please refer to the recovery procedure for more details 200px-Emblem-important.svg.png


Info-icon.png Before continue reading, we suggest to first have a look at Naon Memory organization, where details of memory addresses and size are detailed. Info-icon.png

Flashing images on SPI NOR Flash

SPI NOR Flash is commonly used for:

  • U-Boot (1st and 2nd stage) storage
  • U-Boot environment storage
  • Linux Kernel Image storage

Anyway it can be used as generic storage too (application custom data or even file systems)

Using SPI NOR Flash

U-Boot uses sf (SPI flash sub-system) commands and all its subcommands, to manage SPI NOR flashes.

As with all U-Boot commands, there's a brief help description:

NAON#help sf
sf - SPI flash sub-system

Usage:
sf probe [bus:]cs [hz] [mode]   - init flash device on given SPI bus
                                  and chip select
sf read addr offset len         - read `len' bytes starting at
                                  `offset' to memory at `addr'
sf write addr offset len        - write `len' bytes from memory
                                  at `addr' to flash at `offset'
sf erase offset len             - erase `len' bytes from `offset'

First of all we need to detect which kind of flash is attached to our board. This needs to be done after each boot and before using other sf command, otherwise an error arises:

NAON#sf read 81000000 0 20000
No SPI flash selected. Please run `sf probe'

By using sf probe we can fix the above error:

NAON#sf probe 0:0
8192 KiB AT45DB642D at 0:0 is now current device
NAON#sf read 81000000 0 20000
NAON#

The sf read command read from SPI flash (in the example 128KiB from offset 0) into a ram buffer (at address 0x81000000)

Generally speaking flashing a binary from U-Boot into SPI flash requires

  1. download the binary image (via TFTP)
  2. probe the SPI bus
  3. erase a flash range
  4. write the binary image from RAM to SPI Flash

In the following section we'll see an example of how those generic steps apply to each different image.

Flashing U-Boot 1st Stage

Into the default U-Boot environment there are usually two macro the do all the work:

NAON#print spi_load_1st spi_update_1st
spi_load_1st=tftp ${loadaddr} naon/MLO
spi_update_1st=sf probe 0:0; sf erase 0x0 0x20000; sf write ${loadaddr} 0x0 0x20000

Running them update the U-Boot 1st stage image.

NAON#run spi_load_1st spi_update_1st
link up on port 0, speed 100, full duplex
Using cpsw device
TFTP from server 192.168.0.250; our IP address is 192.168.0.78
Filename 'naon/u-boot.min.spi'.
Load address: 0x81000000
Loading: ############
done
Bytes transferred = 58780 (e59c hex)
8192 KiB AT45DB642D at 0:0 is now current device
NAON#

Flashing U-Boot 2nd Stage

Like the 1st stage, 2nd stage is handled by two macro in U-Boot default environment:

NAON#print loadaddr load spi_update
loadaddr=0x81000000
load=tftp ${loadaddr} naon/u-boot.bin
spi_update=sf probe 0:0; sf erase 0x20000 0x40000; sf write ${loadaddr} 0x20000 0x40000

Here is the result of running them:

NAON#run load spi_update
link up on port 0, speed 100, full duplex
Using cpsw device
TFTP from server 192.168.0.250; our IP address is 192.168.0.78
Filename 'naon/u-boot.bin'.
Load address: 0x81000000
Loading: ######################################
done
Bytes transferred = 193092 (2f244 hex)
8192 KiB AT45DB642D at 0:0 is now current device


Flashing Linux Kernel

Loading and updating kernel image does not differ from U-Boot images:

NAON#print loadaddr loadk spi_updatek
loadaddr=0x81000000
loadk=tftp ${loadaddr} ${bootfile}
spi_updatek=sf probe 0:0; sf erase 0x80000 0x300000; sf write ${loadaddr} 0x80000 0x300000
NAON#run loadk spi_updatek
link up on port 0, speed 100, full duplex
Using cpsw device
TFTP from server 192.168.0.250; our IP address is 192.168.0.78
Filename 'naon/uImage'.
Load address: 0x81000000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ######
done
Bytes transferred = 2688084 (290454 hex)
8192 KiB AT45DB642D at 0:0 is now current device


Info-icon.png Please note that Linux kernel image size may vary, depending on how you configure the kernel itself. The default erase size (3MiB) should be enough large for all configuration but the user needs to take care of changing this value if using a bigger kernel. User should also resize Linux kernel MTD partitioning accordingly Info-icon.png

Flashing images on NAND Flash

NAND Flash can be used for:

  • U-Boot (1st and 2nd stage) storage
  • U-Boot environment storage
  • Linux Kernel Image storage
  • Root File System storage (e.g. by using UBIFS)

Using NAND Flash

U-Boot uses nand (NAND sub-system) commands and all its subcommands, to manage NAND flashes.

As with all U-Boot commands, there's a brief help description:

NAON##help nand
nand - NAND sub-system

Usage:
nand info - show available NAND devices
nand device [dev] - show or set current device
nand read - addr off|partition size
nand write - addr off|partition size
    read/write 'size' bytes starting at offset 'off'
    to/from memory address 'addr', skipping bad blocks.
nand erase [clean] [off size] - erase 'size' bytes from
    offset 'off' (entire device if not specified)
nand bad - show bad blocks
nand dump[.oob] off - dump page
nand scrub - really clean NAND erasing bad blocks (UNSAFE)
nand markbad off [...] - mark bad block(s) at offset (UNSAFE)
nand biterr off - make a bit error at offset (UNSAFE)

First of all we need to configure which ECC algorithm is used by the NAND sub-system. By default, both u-boot and Linux use BCH8.

nandecc command is used to change ECC algorithm:

NAON#help nandecc
nandecc - Switch NAND ECC calculation algorithm b/w hardware and software

Usage:
nandecc [sw|hw <hw_type>]
   [sw|hw]- Switch b/w hardware(hw) & software(sw) ecc algorithm
   hw_type- 0 for Hamming code
            1 for bch4
            2 for bch8
            3 for bch16

NAON#nandecc hw 2
HW ECC BCH8 Selected

Generally speaking flashing a binary from U-Boot into NAND flash requires

  1. download the binary image (via TFTP)
  2. choose the correct ECC algorithm
  3. erase a flash range
  4. write the binary image from RAM to NAND Flash

In the following section we'll see an example of how those generic steps apply to each different image.

Flashing U-Boot 1st Stage

Into the default U-Boot environment there are usually two macro the do all the work:

NAON#print nand_load_1st nand_update_1st
nand_load_1st=mw.b ${loadaddr} 0xFF 0x20000; tftp ${loadaddr} naon/MLO
nand_update_1st=nand erase 0x0 0x20000; nandecc hw 2; nand write.i ${loadaddr} 0x0 0x20000

Running them update the U-Boot 1st stage image.

NAON#run nand_load_1st nand_update_1st
link up on port 0, speed 100, full duplex
Using cpsw device
TFTP from server 192.168.0.250; our IP address is 192.168.0.78
Filename 'naon/MLO
Load address: 0x81000000
Loading: ############
done
Bytes transferred = 58780 (e59c hex)
NAND erase: device 0 offset 0x0, size 0x20000
Erasing at 0x0 -- 100% complete.
OK
HW ECC BCH8 Selected

NAND write: device 0 offset 0x0, size 0x20000
131072 bytes written: OK
NAON#

Flashing U-Boot 2nd Stage

Like the 1st stage, 2nd stage is handled by two macro in U-Boot default environment:

NAON##print load nand_update
load=mw.b ${loadaddr} 0xFF 0x40000; tftp ${loadaddr} dido/u-boot.bin
nand_update=nand erase 0x20000 0x40000; nandecc hw 2; nand write.i ${loadaddr} 0x20000 0x40000

Here is the result of running them:

NAON#run load nand_update
link up on port 0, speed 100, full duplex
Using cpsw device
TFTP from server 192.168.0.250; our IP address is 192.168.0.78
Filename 'naon/u-boot.bin'.
Load address: 0x81000000
Loading: ######################################
done
Bytes transferred = 193092 (2f244 hex)
NAND erase: device 0 offset 0x20000, size 0x40000
Erasing at 0x0 -- 100% complete.
OK
HW ECC BCH8 Selected

NAND write: device 0 offset 0x20000, size 0x40000
131072 bytes written: OK


Flashing Linux Kernel

Loading and updating kernel image does not differ from U-Boot images:

NAON#print loadk nand_updatek
loadk=mw.b ${loadaddr} 0xFF 0x400000; tftp ${loadaddr} ${bootfile}
nand_updatek=nand erase 0xA0000 0x400000; nandecc hw 2; nand write.i ${loadaddr} 0xA0000 0x400000
NAON#run loadk nand_updatek
link up on port 0, speed 100, full duplex
Using cpsw device
TFTP from server 192.168.0.250; our IP address is 192.168.0.78
Filename 'naon/uImage'.
Load address: 0x81000000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ######
done
Bytes transferred = 2688084 (290454 hex)
NAND erase: device 0 offset 0xA0000, size 0x400000
Erasing at 0x0 -- 100% complete.
OK
HW ECC BCH8 Selected

NAND write: device 0 offset 0xA0000, size 0x400000
4194304 bytes written: OK


Info-icon.png Please note that Linux kernel image size may vary, depending on how you configure the kernel itself. The default erase size (4MiB) should be enough large for all configuration but the user needs to take care of changing this value if using a bigger kernel. User should also resize Linux kernel MTD partitioning accordingly Info-icon.png