*** The Linux MTD, JFFS HOWTO *** (work in progress, please contribute if you have anything) $Id: mtd-jffs-HOWTO.txt,v 1.16 2001/08/13 23:17:55 dwmw2 Exp $ Last Updated: Compiled/Written By: Vipin Malik (vipin@embeddedLinuxWorks.com) Other author's contributions as noted in the text. **ABOUT: This document will attempt to describe setting up the MTD (Memory Technology Devices), DOC, CFI and the JFFS (Journaling Flash File System) under Linux versions 2.2.x and 2.4.x This is work in progress and (hopefully) with the help of others on the mtd and jffs mailing lists will become quite a comprehensive document. Please mail any comments/corrections/contributions to vipin@embeddedLinuxWorks.com Please DO NOT send questions to him directly, rather send them to the mailing lists (see below). **************************** NO WARRANTY ***************************** # This HOWTO is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # If you break something you get to keep both parts! Follow these # directions at YOUR OWN RISK. # See the GNU General Public License for more details. ********************************************************************** *** Getting Started: If you want to seriously design a project with MTD/JFFS please subscribe to the respective mailing lists. Both are managed by majordomo. MTD: To subscribe, see http://lists.infradead.org/mailman/listinfo/linux-mtd-cvs or send an email to linux-mtd-request@lists.infradead.org containing the line "subscribe" in the body. DO NOT SEND SUBSCRIBE REQUESTS TO THE LIST ITSELF, which is at linux-mtd@lists.infradead.org. JFFS: To subscribe, send an email to majordomo@axis.com containing the line "subscribe jffs-dev" in the body. DO NOT SEND SUBSCRIBE REQUESTS TO THE LIST ITSELF, which is at jffs-dev@axis.com. The home page for the two projects are located at: MTD/DOC/ http://www.linux-mtd.infradead.org/ JFFS http://developer.axis.com/software/jffs/ The MTD mail archive is at: http://www.linux-mtd.infradead.org/list-archive/ The JFFS mail archive is at: http://mhonarc.axis.se/jffs-dev/threads.html A general, vendor agnostic, non commercial site for Embedded Linux Systems is at: http://www.EmbeddedLinuxWorks.com (Here you will find articles about using IDE flash disks in embedded systems, reports of JFFS/JFFS2 power fail reliability tests, tips on using JFFS systems in your design, details on how to boot the x86 Linux kernel from FLASH without using a BIOS and (hopefully in due course) a vibrant community of developers discussing issues related to embedded Linux with each other on the message boards ;) ** MTD Flash Device Database: ** In the above mentioned site, you will also find a MTD Flash device database. This database contains a list of flash devices successfully working with the MTD drivers. If you manage to get a particular flash device (or Disk On Chip etc.) to work with any MTD driver, please take a few minutes to enter the relevant info in this database for the benefit of future users. Anyone can make an entry or view any info there. Access the MTD Flash database directly at: http://www.embeddedLinuxWorks.com/db.html ** Power fail safe embedded database ** There is a seperate project (with its own mailing list) going on to develop a zero latency write, power fail safe (small) embedded database to use on JFFS2. Read more on why we need such a beast at: http://www.embeddedLinuxWorks.com/articles/db_project.html *** Getting the latest code: The entire MTD/DOC/JFFS (and some utils) source code may be downloaded via anonymous CVS. Follow the following steps: 1.Make sure that you are root. 2. cd /usr/src 3. cvs -d :pserver:anoncvs@cvs.infradead.org:/home/cvs login (password: anoncvs) 4. cvs -d :pserver:anoncvs@cvs.infradead.org:/home/cvs co mtd This will create a dir called mtd under /usr/src You now have two options depending on what series of the Linux Kernel you want to work with. There is an extra step involved with the 2.2 series kernels as they do not have any MTD code in them. Note: Check under /dev/ If you do not have devices like mtd0,1,2 and mtdblock0,1,2 etc. run the MAKEDEV utility found under mtd/util as: #sh /usr/src/mtd/util/MAKEDEV This will create all the proper devices for you under /dev ** With 2.2.x series kernels: (Note that as far as I can tell, mtd and jffs does not work as modules under the 2.2.x series of kernels. If you want to do modules I would recommend that you upgrade to the 2.4.x series of kernels). Get the 2.2.17 or 2.2.18 kernel source code from your favorite source (ftp.kernel.org) and install the kernel under /usr/src/linux-2.2.x with /usr/src/linux being a symbolic link to your kernel source dir. Configure the kernel to your desired options (by doing a make config (or menuconfig or xconfig), and make sure that the kernel compiles ok. Download the mtd patch from: ftp://ftp.infradead.org/pub/mtd/patches Move the patch to /usr/src/linux and do patch -p1 < Make sure that the patch was applied ok without any errors. This will add the mtd functionality to your basic kernel and bring the mtd code up-to date to the date of the patch. You have two choices here. You may do a make config and configure in mtd stuff with the current code or you may want to get the latest code from the cvs patched in. If you want the latest CVS code patched in follow the 2.4.x directions below. ** With 2.4.x series of kernels: If you want the latest code from CVS (available under /usr/src/mtd) do: 1. cd /usr/src/mtd/patches 2. sh patchin.sh /usr/src/linux This will create symbolic links from the /usr/src/linux/drivers/mtd/ to the respective files in /usr/src/mtd/kernel/ The same happens with /usr/src/linux/fs/jffs and /usr/src/linux/include/linux/mtd Now you have the latest cvs code available with the kernel. You may now do a make config (or menuconfig or xconfig) and config the mtd/jffs etc. stuff in as described below. *** Configuring MTD and friends for DOC in the Kernel: Do not use any mtd modules with the 2.2.x series of kernels. As far as I can tell, it does not work even if you can get it to compile ok. Modules work ok with the 2.4.x series of kernels. Depending on what you want to target you have some choices here, namely: *** 1. Disk On Chip Devices (DOC): For these, you need to turn on (or make into modules) the following: * MTD core support * Debugging (set the debug level as desired) * Select the correct DOC driver depending on the DOC that you have. (1000, 2000 or Millennium). Note that the CONFIG_MTD_DOC2000 option is a driver for both the DiskOnChip 2000 and the DiskOnChip Millenium devices. If you have problems with that you could try the alternative DiskOnChip Millennium driver, CONFIG_MTD_DOC2001. To get the DiskOnChip probe code to use the Millennium-specific driver, you need to edit the code in docprobe.c and undefine DOC_SINGLE_DRIVER near the beginning. * Unless you are doing something out of the ordinary, it shouldn't be necessary for you to enable the "Advanced detection options for DiskOnChip" option. * If you do so, you can specify the physical address at which to probe for the DiskOnChip. Normally, the probe code will probe at every 0x2000 bytes from 0xC8000 to 0xEE000. Changing the CONFIG_MTD_DOCPROBE_ADDRESS option will allow you to specify a single location to be probed. Note that your DiskOnChip is far more likely to be mapped at 0xD0000 than 0xD000. Use the real physical address, not the segment address. If you leave the address blank (or just don't enable the advanced options), the code will *auto probe*. This works quite well (at least for me). Try it first. * Probe High Addresses will probe in the top of the possible memory range rather than in the usual BIOS ROM expansion range from 640K - 1 Meg. This has to do with LinuxBIOS. See the mailing list archive for some e-mails regarding this. If you don't know what I am talking about here, leave this option off. * Probe for 0x55 0xaa BIOS signature. Unless you've got LinuxBIOS on your DiskOnChip Millennium and need it to be detected even though you've replace the IPL with your chipset setup code, say yes here. Leave everything else off, till you reach... User Modules and Translation layers: * Direct char device access - yes * NFTL layer support - yes * Write support for NFTL(beta) - yes Note that you don't need 'MTDBLOCK' support. That is something entirely different - a caching block device which works directly on the flash chips without wear levelling. Save everything, make dep, make bzImage, make modules, make modules_install Note: If you downloaded the 2.4.x series kernels and your original installed distribution came with the 2.2.x series of kernels then you need to download the latest modutils (from ftp.kernel.org/utils/kernel), else make modules_install or depmod -a will fail for the new 2.4.x kernels. Move everything to the right place, install the kernel, run lilo and reboot. If you compiled the mtd stuff into the kernel (see later section if you compiled as modules- which is what I prefer as you don't have to keep rebooting) then look for the startup messages. In particular pay attention to the lines when the MTD DOC header runs. It will say something like: "DiskOnChip found at address 0xD0000 (your address may be different)" "nftla1" The above shows that the DOC was detected fine and one partition was found and assigned to /dev/nftla1. If further partitions are detected, they will be assigned to /dev/nftla2 etc. Note that the MTD device is /dev/mtd0 and details are available by doing a: #cat /proc/mtd dev: size erasesize name mtd0: 02000000 00004000 "DiskOnChip 2000" /dev/nftla1,2,3 are "regular" block disk partitions and you may mke2fs on them to put a ext2 fs on it. Then they may be mounted in the regular way. When the DiskOnChip is detected and instead of nftla1,2,3... you get something like: "Could not find valid boot record" "Could not mount NFTL device" ...first make sure you have the latest DiskOnChip and NFTL code from the CVS repository. If that doesn't help you, especially if the driver has previously exhibited strange and buggy behaviour, and if the DOS driver built into the device no longer works, then it's possible that you have a "hosed" (that's a technical term) disk. You need to "un-hose" it. To help you out in that department there is a utility available under /usr/src/mtd/util called nftl_format. DO NOT EVER USE THE nftl_format UTILITY WITHOUT FIRST SEEKING ADVICE ON THE MAILING LIST. It will erase all blocks on the device, potentially losing the factory-programmed information about bad blocks. (Someone really ought to fix it one of these days - ed) Essentially after your disk have been detected but complains about "Could not mount NFTL device", just run #./nftl_format /dev/mtd0 (if your device was installed under mtd0, see cat /proc/mtd/). You should unload the nftl driver module before using the nftl_format utility, and reload it afterwards. Reformatting the NFTL underneath the driver is not a recipe for happiness. If the driver hasn't recognised the NFTL format, then it's safe - reboot or reload the module after running nftl_format and it should then recognise it again. If your device "erasesize" is 8k (0x2000), then the utility will go ahead and format it. Just reboot and this time the drivers will complain about an "unknown partition table". Don't worry. Just do: # fdisk /dev/nftla and create some partitions on them. TaDa! You may now e2fsck and others on these partitions. Note that if you don't want more than one partition you don't need to muck about with partitions at all - just make a filesystem on the whole device /dev/nftla instead of partitioning and using /dev/nftla1. *** IF you compiled the mtd stuff as modules (What I prefer): Make sure that you have done a depmod -a after you reboot with the new kernel. Then just #modprobe -a doc2000 nftl mtdchar mtdblock You have now loaded the core stuff. The actual detection takes place only when you load the docprobe module. Then do #modprobe -a docprobe You should then see the messages described in the section above. Follow the directions and procedures are outlined in the section above (where you would have compiled the mtd/DOC stuff into the kernel). *** 2. Raw Flash (primarily NOR) chips This are multiple (or just one) flash IC's that may be soldered on your board or you may be designing some in. Unlike the DOC device, these are usually linearly memory mapped into the address space (though not necessarily, they may also be paged). MTD can handle x8, x16 or x32 wide memory interfaces, using x8, x16 (even x32 chips (are they such a thing)?- confirm). At present CFI stuff seems to work quite well and these are the type of chips on my board. Hence I will describe them first. Maybe someone with JEDEC chips can describe that. You must use (for all practical purposes that involve writing) JFFS on raw flash MTD devices. This is because JFFS provides a robust writing and wear leveling mechanism. See FAQ for more info. If you only want the file-system to be writable while you're developing, but will ship the units read-only, it's acceptable to use the MTDBLOCK device, which performs writes by reading the entire erase block, erasing it, changing the range of bytes which were written to, and writes it back to the flash. Obviously that's not something you want happening in production, but for development it's OK. *** Configuring the kernel with MTD/CFI/JFFS and friends. Turn off all options for MTD except those mentioned here. * MTD support (the core stuff) * Debugging -yes (try level 3 initially) * Support for ROM chips in bus mapping -yes * CFI (common flash interface) support -yes * Specific CFI flash geometry selection -yes *