10.4. MTD UtilitiesThe 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
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
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 SystemCreating 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
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?
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
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
|