NAND Flash Programming

NAND Flash Layout

MTD Name Offset Size Usage
mtd0 MTNCG-NANDFlash 0x00000000 0x10000000 Whole NAND
mtd1 AT91Bootstrap 0x00000000 0x00020000 Bootstrap [bootstrap.bin]
mtd2 UBoot 0x00020000 0x00040000 U-Boot [u-boot.bin]
mtd3 UBoot Config 0x00060000 0x00020000 U-Boot environment
mtd4 UBoot Redundant Config 0x00080000 0x00020000 U-Boot redundant environment
mtd5 uImage 0x000A0000 0x00760000 Linux Kernel [uImage.bin]
mtd6 Config 0x00800000 0x00800000 Configuration [/var/config]
mtd7 Oem Config 0x01000000 0x00800000 OEM Specific configuration [not used by default]
mtd8 Rootfs 0x01800000 0x0E800000 root filesystem [rootfs.jffs]

Total Size: 256 MB
Block/Sector Size: 128 KB

Flashing from U-Boot

U-Boot can be accessed at boot time from the DEBUG serial port.

  • If you have an MTCDP and are using the MultiConnect OCG Break-Out Board, you may connect the Break-Out Board to the MTCDP using the 36-pin cable provided, and then connect a standard 9-pin serial cable to the DEBUG port on the Break-out Board.
  • If you have an MTCDP without a MultiConnect OCG Break-Out Board, you will have to remove the case and plug in the provided DEBUG serial cable to the 3-pin connector located on the board. See How to Setup Serial Console Cable.
  • If using the MT100EOCG embedded gateway, connect the serial cable to the 3-pin connector on the developer board.

Setting up the U-Boot Environment

Install and configure a TFTP server on your development workstation. For example using in.tftpd and xinetd the following configuration will listen on port 69 and set /tftboot as the tftp root dir.

/etc/xinetd.d/tftp:

service tftp
{
protocol        = udp
port            = 69
socket_type     = dgram
wait            = yes
user            = nobody
server          = /usr/sbin/in.tftpd
server_args     = -s /tftpboot
disable         = no
}

Run minicom and configure the serial port attached to the device to [115200 8N1] with hardware flow control OFF.

Power on the device after connecting the debug cable. You will need to press a key to interrupt U-Boot from booting the system — look for the Hit any key to stop autoboot message.

U-Boot 1.3.4 (Mar 26 2010 - 10:35:18)

DRAM:  64 MB
NAND:  256 MiB
In:    serial
Out:   serial
Err:   serial
Net:   macb0
macb0: link up, 100Mbps half-duplex (lpa: 0x40a1)
Hit any key to stop autoboot:  0 
U-Boot> 

Some units come already configured with a U-Boot environment that makes flashing the device simple. To check the contents of the U-Boot environment, run printenv and check for variables named tftp_kernel and tftp_rootfs, etc.

U-Boot> printenv
baudrate=115200
ethaddr=00:08:00:87:00:02
bootargs=mem=64M console=ttyS0,115200 root=/dev/mtdblock8 ro rootfstype=jffs2
bootcmd=nboot.jffs2 ${loadaddr} 0 ${kernel_addr}; bootm ${loadaddr}
bootdelay=3
...
tftp_kernel=tftp ${loadaddr} ${kernel_file}; run erase_kernel; nand write.jffs2 ${fileaddr} ${kernel_addr} ${filesize}
tftp_config=tftp ${loadaddr} ${config_file}; run erase_config; nand write.jffs2 ${fileaddr} ${config_addr} ${filesize}
tftp_oem=tftp ${loadaddr} ${oem_file}; run erase_oem; nand write.jffs2 ${fileaddr} ${oem_addr} ${filesize}
tftp_rootfs=tftp ${loadaddr} ${rootfs_file}; run erase_rootfs; nand write.jffs2 ${fileaddr} ${rootfs_addr} ${filesize}
krb=run tftp_kernel; run tftp_rootfs; boot
rb=run tftp_rootfs; boot
stdin=serial
stdout=serial
stderr=serial

Environment size: 2445/131067 bytes
U-Boot>

If these variables do exist, then modify the serverip, ipaddr, and netmask variables to match your network and device and save the settings to make the changes permanent. Then continue to the “Flash the Kernel from U-Boot” section below.

U-Boot> set ipaddr 192.168.2.1
U-Boot> set serverip 192.168.2.2
U-Boot> set netmask 255.255.255.0
U-Boot> save
Saving Environment to NAND...
Erasing redundant Nand...
Erasing at 0x80000 -- 100% complete.
Writing to redundant Nand... done
U-Boot> save
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x60000 -- 100% complete.
Writing to Nand... done
U-Boot>

If the tftp_kernel and tftp_rootfs variables do not exist in the U-Boot environment, follow the instructions below to update the U-Boot environment for flashing.

Copy the U-Boot environment setup script to a location with a shorter path. The full path needs to be short enough to fit in the Minicom run script menu.

cp $OETREE/multitech/contrib/uboot-setenv $HOME/uboot-setenv

Edit ${HOME}/uboot-setenv to match your network and device.

send setenv serverip              192.168.2.2
send setenv ipaddr                192.168.2.1
send setenv netmask               255.255.255.0

Run the U-Boot environment setup script. At minicom type CTRL-A G and enter ${HOME}/uboot-setenv as the name of the script to run. When the script finishes it should save and print out the environment. Make sure you expand ${HOME} to your actual home dir when entering the script name.

Version 2.4 of Minicom (the version in Ubuntu 10.04) has a bug where scripts never ever exit. In this case, the variables actually get set properly so after the script has run for a while, exit Minicom, restart it, and run ‘printenv’ to see if the changes took effect.

Flash the Kernel from U-Boot

Make sure oe_uImage.bin is in your tftpboot dir then run the tftp kernel command.
If you have TFTPBOOT_DIR set in your env-oe.sh script then this should happen automatically after building.

U-Boot> run tftp_kernel
macb0: link up, 100Mbps full-duplex (lpa: 0x45e1)
Using macb0 device
TFTP from server 192.168.2.2; our IP address is 192.168.2.1
Filename 'oe_uImage.bin'.
Load address: 0x21400000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
########
done
Bytes transferred = 1703556 (19fe84 hex)

NAND erase: device 0 offset 0xa0000, size 0x760000
Erasing at 0x7e0000 -- 100% complete.
OK

NAND write: device 0 offset 0xa0000, size 0x19fe84

Writing data at 0x23f800 -- 100% complete.
1703556 bytes written: OK
U-Boot>

Flash the Rootfs from U-Boot

Make sure oe_rootfs.jffs2 is in your tftpboot dir then run the tftp rootfs command.
If you have TFTPBOOT_DIR set in your env-oe.sh script then this should happen automatically after building.

U-Boot> run tftp_rootfs
macb0: link up, 100Mbps full-duplex (lpa: 0x45e1)
Using macb0 device
TFTP from server 192.168.2.2; our IP address is 192.168.2.1
Filename 'oe_rootfs.jffs2'.
Load address: 0x21400000
Loading: #################################################################
#################################################################
#################################################################
...
#################################################################
######
done
Bytes transferred = 11010048 (a80000 hex)

NAND erase: device 0 offset 0x1800000, size 0xe800000
Erasing at 0xffe0000 -- 100% complete.
OK

NAND write: device 0 offset 0x1800000, size 0xa80000

Writing data at 0x227f800 -- 100% complete.
11010048 bytes written: OK
U-Boot>

U-Boot may not complete a response to a delayed ARP request. If your tftp transfers are timing out, you may need to add an entry to the ARP cache manually. You do not need to do anything unless you are having a problem.

$ # Add an entry for the device 00:D0:A0:02:0D:E1 with IP address 192.168.2.1 reachable via interface eth2
$ sudo arp -i eth2 -s 192.168.2.1 00:D0:A0:02:0D:E1
$ # View the ARP cache entries on interface eth2
$ arp -n -i eth2
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.2.1              ether   00:D0:A0:02:0D:E1   CM                    eth2

Flashing from Linux

The kernel and root filesystem can also be flashed from Linux as part of the reboot process. The device will check for the existence of a file named /var/volatile/do_flash_upgrade to indicate that it should attempt to flash itself on reboot. If /var/volatile/do_flash_upgrade exists, it will look for the upgrade files in two locations: /var/volatile/flash-upgrade and /media/card/flash-upgrade and flash itself.

Prior to CoreCDP 2, creating /var/volatile/do_flash_upgrade was not necessary. The addition of this step makes the intention to upgrade more explicit and prevents unintended repeated flashing from the SD card.

Summary

Copy kernel and rootfs to:
/var/volatile/flash-upgrade/uImage.bin
/var/volatile/flash-upgrade/rootfs.jffs2
OR
/media/card/flash-upgrade/uImage.bin
/media/card/flash-upgrade/rootfs.jffs2

Run touch /var/volatile/do_flash_upgrade
Run reboot

The file names must match above exactly and are case-sensitive.

Step-by-step

On the device, first create the destination directory:

mkdir /var/volatile/flash-upgrade

On your development machine, use SCP to transfer the files to the device. The following example shows flashing corecdp-base-image on an MTCDP device (MACHINE=”mtcdp”).

cd ${OETREE}/build/tmp/deploy/eglibc/images/mtcdp
scp uImage-mtcdp.bin root@192.168.2.1:/var/volatile/flash-upgrade/uImage.bin
scp corecdp-base-image-mtcdp.jffs2 root@192.168.2.1:/var/volatile/flash-upgrade/rootfs.jffs2

If you have TFTPBOOT_DIR set in your env-oe.sh script, you may also use the linked files in /tftpboot instead.

If you choose to copy uImage.bin and rootfs.jffs2 into the tmpfs mounted at /var/volatile, you will have to make sure there is enough space to fit the images in memory before hand. If you need to flash a larger image and have an SD card inserted, you can copy the images into /media/card instead.

After transferring the files to the proper location, create /var/volatile/do_flash_upgrade and reboot to initiate the upgrade.

# touch /var/volatile/do_flash_upgrade
# reboot

Broadcast message from root (ttyS0) (Tue Nov 15 05:35:42 2011):

The system is going down for reboot NOW!
INIT: Sending processes the TERM signal
Stopping Dropbear SSH server: stopped /usr/sbin/dropbear (pid 303)
dropbear.
Stopping Vixie-cron.
Deconfiguring network interfaces... done.
Stopping Lighttpd Web Server: stopped /usr/sbin/lighttpd (pid 342)
lighttpd.
Stopping syslogd/klogd: stopped syslogd (pid 309)
stopped klogd (pid 311)
done
Sending all processes the TERM signal...
eth0: link down
Sending all processes the KILL signal...
Unmounting remote filesystems...
/var/volatile/flash-upgrade not present, skipping

Starting flash upgrade from /media/card/flash-upgrade...
Flashing /dev/mtd5 (uImage) with /media/card/flash-upgrade/uImage.bin...
flash_eraseall has been replaced by `flash_erase  0 0`; please use it
Erasing 128 Kibyte @ 740000 -- 100 % complete 
Writing data to block 0 at offset 0x0
Writing data to block 1 at offset 0x20000
Writing data to block 2 at offset 0x40000
Writing data to block 3 at offset 0x60000
Writing data to block 4 at offset 0x80000
Writing data to block 5 at offset 0xa0000
Writing data to block 6 at offset 0xc0000
Writing data to block 7 at offset 0xe0000
Writing data to block 8 at offset 0x100000
Writing data to block 9 at offset 0x120000
Writing data to block 10 at offset 0x140000
Writing data to block 11 at offset 0x160000
Writing data to block 12 at offset 0x180000
Writing data to block 13 at offset 0x1a0000
Writing data to block 14 at offset 0x1c0000
Flashing /dev/mtd8 (rootfs) with /media/card/flash-upgrade/rootfs.jffs2...
Deactivating swap...
Unmounting local filesystems...
umount2: Device or resource busy
umount: none busy - remounted read-only
umount2: Device or resource busy
umount: devtmpfs busy - remounted read-only
flash_eraseall has been replaced by `flash_erase  0 0`; please use it
Erasing 128 Kibyte @ 0 --  0 % complete flash_erase:  Cleanmarker written at 0
Erasing 128 Kibyte @ 20000 --  0 % complete flash_erase:  Cleanmarker written at 20000
...
Writing data to block 593 at offset 0x4a20000
Writing data to block 594 at offset 0x4a40000
Writing data to block 595 at offset 0x4a60000
Rebooting...
Restarting system.