Section 10.4. MTD Utilities


10.4. MTD Utilities

The MTD package contains a number of system utilities useful for setting up and managing your MTD subsystem. The utilities are built separately from the primary MTD subsystem, which should be built from within your Linux kernel source tree. The utilities can be built in a similar manner to any other cross-compiled user space code.

You must use caution when using these utilities because there is no protection from mistakes. A single-digit typo can wipe out the bootloader on your hardware platform, which can definitely ruin your day unless you've backed it up and know how to reprogram it using a JTAG Flash programmer.

In keeping with a common practice throughout this book, we cannot devote sufficient space to cover every MTD utility. We highlight the most common and useful ones, and leave it as an exercise for the reader to explore the rest. A recent MTD snapshot contained more than 20 binary utilities.

The flash_* family of utilities is useful for raw device operations on an MTD partition. These include flashcp, flash_erase, flash_info, flash_lock, flash_unlock, and others. Hopefully their names are descriptive enough to give some idea of their function. After partitions are defined and enumerated as kernel devices, any of these user space utilities can be run on a partition. We repeat the warning we issued earlier: If you execute flash_erase on the partition containing your bootloader, you'll be the proud owner of a silicon paperweight. If you intend to experiment like this, it's a good idea to have a backup of your bootloader image and know how to re-Flash it using a hardware JTAG emulator or other Flash programming tool.

Our new partition created in Listing 10-8 (MyKernel) shows up in the kernel running on the Coyote board, as detailed in Listing 10-13. Here you can see the new partition we created instantiated as the kernel device mTD1.

Listing 10-13. Kernel MTD Partition List

root@coyote:~# cat /proc/mtd dev:    size   erasesize  name mtd0: 00060000 00020000 "RedBoot" mtd1: 00160000 00020000 "MyKernel" mtd2: 00001000 00020000 "RedBoot config"x mtd3: 00020000 00020000 "FIS directory"

Using the MTD utilities, we can perform a number of operations on the newly created partition. The following shows the results of a flash_erase command on the partition:

# flash_erase /dev/mtd1 Erase Total 1 Units Performing Flash Erase of length 131072 at offset 0x0 done


To copy a new kernel image to this partition, use the flashcp command:

root@coyote:~# flashcp /workspace/coyote-40-zImage /dev/mtd1


It gets a bit more interesting working with a root file system partition. We have the option of using the bootloader or the Linux kernel to place the initial image on the Redboot flash partition. First, we use Redboot to create the new partition that will hold our root file system. The following command creates a new partition on the Flash called RootFS starting at physical memory 0x50300000, with a length of 30 blocks. Remember, a block, generically called an erase unit, is 128KB on this Flash chip.

RedBoot> fis create -f 0x50300000 -l 0x600000 -n RootFS


Next, we boot the kernel and copy the root file system image into the new partition we have named RootFS. This is accomplished with the following command from a Linux command prompt on your target board. Note that this assumes you have already placed your file system image in a directory accessible to your board. As mentioned many times throughout this book, NFS is your best choice for development.

root@coyote:~# flashcp /rootfs.ext2/dev/mtd2


The file system can be anywhere from a couple megabytes up to the largest size we have allowed on this partition, so this can take some time. Remember, this operation involves programming (sometimes called flashing) the image into the Flash memory. After copying, we can mount the partition as a file system. Listing 10-14 displays the sequence.

Listing 10-14. Mounting MTD Flash Partition as ext2 File System

root@coyote:~# mount -t ext2/dev/mtdblock2 /mnt/remote ro root@coyote:~# ls -l /mnt/remote/ total 16 drwxr-xr-x  2 root root 1024 Nov 19  2005 bin drwxr-xr-x  2 root root 1024 Oct 26  2005 boot drwxr-xr-x  2 root root 1024 Nov 19  2005 dev drwxr-xr-x  5 root root 1024 Nov 19  2005 etc drwxr-xr-x  2 root root 1024 Oct 26  2005 home drwxr-xr-x  3 root root 1024 Nov 19  2005 lib drwxr-xr-x  3 root root 1024 Nov 19  2005 mnt drwxr-xr-x  2 root root 1024 Oct 26  2005 opt drwxr-xr-x  2 root root 1024 Oct 26  2005 proc drwxr-xr-x  2 root root 1024 Oct 26  2005 root drwxr-xr-x  2 root root 1024 Nov 19  2005 sbin drwxr-xr-x  2 root root 1024 Oct 26  2005 srv drwxr-xr-x  2 root root 1024 Oct 26  2005 sys drwxr-xr-x  2 root root 1024 Oct 26  2005 tmp drwxr-xr-x  6 root root 1024 Oct 26  2005 usr drwxr-xr-x  2 root root 1024 Nov 19  2005 var root@coyote:~#

Listing 10-14 has two important subtleties. Notice that we have specified /dev/mtdblock2 on the mount command line. This is the MTD block driver that enables us to access the MTD partition as a block device. Using /dev/mtd2 as a specifier instructs the kernel to use the MTD character driver. Both the mtdchar and mtdblock are pseudodrivers used to provide either character-based or block-oriented access to the underlying Flash partition. Because mount expects a block device, you must use the block-device specifier. Figure 10-1 shows the kernel configuration that enables these access methods. The respective kernel configuration macros are CONFIG_MTD_CHAR and CONFIG_MTD_BLOCK.

The second subtlety is the use of the read-only (ro) command-line switch on the mount command. It is perfectly acceptable to mount an ext2 image from Flash using the MTD block emulation driver for read-only purposes. However, there is no support for writing to an ext2 device using the mtdblock driver. This is because ext2 has no knowledge of Flash erase blocks. For write access to a Flash-based file system, we need to use a file system with Flash knowledge, such as JFFS2.

10.4.1. JFFS2 Root File System

Creating a JFFS2 root file system is a straightforward process. In addition to compression, JFFS2 supports wear leveling, a feature designed to increase Flash lifetime by fairly distributing the write cycles across the blocks of the device. As pointed out in Chapter 9, Flash memory is subject to a limited number of write cycles. Wear leveling should be considered a mandatory feature in any Flash-based file system you employ. As mentioned elsewhere in this book, you should consider Flash memory as a write-occasional medium. Specifically, you should avoid allowing any processes that require frequent writes to target the Flash file system. Be especially aware of any logging programs, such as syslogd.

We can build a JFFS2 image on our development workstation using the ext2 image we used on our Redboot RootFS partition. The compression benefits will be immediately obvious. The image we used in the previous RootFS example was an ext2 file system image. Here is the listing in long (-l) format:

# ls -l rootfs.ext2 -rw-r--r--  1 root root 6291456 Nov 19 16:21 rootfs.ext2


Now let's convert this file system image to JFFS2 using the mkfs.jffs2 utility found in the MTD package. Listing 10-15 shows the command and results.

Listing 10-15. Converting RootFS to JFFS2

# mount -o loop rootfs.ext2/mnt/flash/ # mkfs.jffs2 -r /mnt/flash -e 128 -b -o rootfs.jffs2 # ls -l rootfs.jffs2 -rw-r--r--  1 root root 2401512 Nov 20 10:08 rootfs.jffs2 #

First we mount the ext2 file system image on a loopback device on an arbitrary mount point on our development workstation. Next we invoke the MTD utility mkfs.jffs2 to create the JFFS2 file system image. The -r flag tells mkfs.jffs2 where the root file system image is located. The -e instructs mkfs.jffs2 to build the image while assuming a 128KB block size. The default is 64KB. JFFS2 does not exhibit its most efficient behavior if the Flash device contains a different block size than the block size of the image. Finally, we display a long listing and discover that the resulting JFFS2 root file system image has been reduced in size by more than 60 percent. When you are working with limited Flash memory, this is a substantial reduction in precious Flash resource usage.

Take note of an important command-line flag passed to mkfs.jffs2 in Listing 10-15. The -b flag is the -big-endian flag. This instructs the mkfs.jffs2 utility to create a JFFS2 Flash image suitable for use on a big-endian target. Because we are targeting the ADI Engineering Coyote board, which contains an Intel IXP425 processor running in big-endian mode, this step is crucial for proper operation. If you fail to specify big endian, you will get several screens full of complaints from the kernel as it tries to negotiate the superblock of a JFFS2 file system that is essentially gibberish.[2] Anyone care to guess how I remembered this important detail?

[2] The kernel can be configured to operate with a wrong-endian MTD file system, at the cost of reduced performance. In some configurations (such as multiprocessor designs), this can be a useful feature.

In a similar manner to the previous example, we can copy this image to our Redboot RootFS Flash partition using the flashcp utility. Then we can boot the Linux kernel using a JFFS2 root file system. Listing 10-16 provides the details, running the MTD utilities on our target hardware.

Listing 10-16. Copying JFFS2 to RootFS Partition

root@coyote:~# cat /proc/mtd dev:    size   erasesize  name mtd0: 00060000 00020000 "RedBoot" mtd1: 00160000 00020000 "MyKernel" mtd2: 00600000 00020000 "RootFS" mtd3: 00001000 00020000 "RedBoot config" mtd4: 00020000 00020000 "FIS directory" root@coyote:~# flash_erase /dev/mtd2 Erase Total 1 Units Performing Flash Erase of length 131072 at offset 0x0 done root@coyote:~# flashcp /rootfs.jffs2 /dev/mtd2 root@coyote:~#

It is important to note that you must have the JFFS2 file system enabled in your kernel configuration. Execute make ARCH=<arch> gconfig and select JFFS2 under File Systems, Miscellaneous File Systems. Another useful hint is to use the -v (verbose) flag on the MTD utilities. This provides progress updates and other useful information during the Flash operations.

We have already seen how to boot a kernel with the Redboot exec command. Listing 10-17 details the sequence of commands to load and boot the Linux kernel with our new JFFS2 file system as root.

Listing 10-17. Booting with JFFS2 as Root File System

RedBoot> load -r -v -b 0x01008000 coyote-zImage Using default protocol (TFTP) Raw file loaded 0x01008000-0x0114decb, assumed entry at 0x01008000 RedBoot> exec -c "console=ttyS0,115200 rootfstype=jffs2 root=/dev/mtdblock2" Using base address 0x01008000 and length 0x00145ecc Uncompressing Linux...... done, booting the kernel. ...



Embedded Linux Primer(c) A Practical Real-World Approach
Embedded Linux Primer: A Practical Real-World Approach
ISBN: 0131679848
EAN: 2147483647
Year: 2007
Pages: 167

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net