Hello everyone. I'm using a mini2440, with a majorly trimmed down version of the default Linux (I took out Qtopia). I've got a CGI script which extracts the header information, kernel and filesystem info out of the image, then needs to load it onto NAND. However, I'm unclear as to the process. Let's say for the moment, that I can hold, in memory (or on a staging partition on SD if absolutely needed, but I don't see why it'd be needed) the filesystem image (yaffs2 uncompressed). For the sake of simplicity, let's say it's the same filesystem it currently is running (the same one I uploaded through USB). Now then, from the booted system, I need to somehow unlock NAND so I can write the bits to flash that I have in memory. Anyone have any pointers? Maybe a pre-existing tool I can just use on the board? Unfortunately, it's not going to be practical any time I want to upgrade the software on this board to have USB connectivity, as it'll be out in a building at a communications tower site, way remote -- not only that, but there will be several other of these devices at similar structures spread across my area. So I need to get a remote firmware upgrade mechanism functional. Any help would be appreciated.
I should post a followup with some actual details. User uploads an image via a web script (yet unimplemented). Take that image, extract the 3 parts, header, kernel and filesystem, store them to a staging partition for now on SD after it verifies checksums or bails with an error. (implemented, working) CGI script then spawns off a worker which begins the actual upgrade. The problem is with the last step, I know how to do it all except for the part where i need to erase nand, and write the kernel to the mtd partition 1, and the filesystem to mtd partition 2. I keep getting this sinking suspicion that a tool called "nand" which has a "erase" argument is required, however I can't seem to find one. I did put mtd-tools on the device after cross compiling for armel using the toolchain here, but nanderase just bails on an illegal instruction, as does nandwrite when going to write a yaffs image to nand. 3 days I've been stuck on this point, any help -- any at all would be greatly appreciated.
Jeremy, As I am not familiar with this issue I asked a fellow work buddy if he had any suggestions. Seems he had quite a bit to pass on! Hope there is some help there for you. Would you publish the outcome if you sort it out? *** I think it is best to use the mtd_debug and flash_erase programs in mtd-tools. It basically calls IOCTL's to the kernel for erasing and writing to the nand/nor chips. mtd-tools don't need to know whether it's a NAND or NOR as the appropriate driver in the kernel, in your case, NAND, will do the actual erase and write operations including the appropriate locking and unlocking. If mtd-tools has been compiled correctly, it can be used as in the following: (I'm using NOR flash here.)  Get info about the flash partition: # ./mtd_debug info /dev/mtd2 mtd.type = MTD_NORFLASH mtd.flags = MTD_CAP_NORFLASH mtd.size = 1048576 (1M) mtd.erasesize = 131072 (128K) mtd.writesize = 1 mtd.oobsize = 0 mtd.ecctype = MTD_ECC_NONE regions = 0  Erasing the flash partition: # ./flash_erase /dev/mtd2 0 8 Basically the 2nd parameter is the number of the start block. The 3rd parameter is the number of erase blocks, in this case "1048576 / 131072 = 8" for the entire partition as shown above.  Then write the image: # ./mtd_debug write /dev/mtd2 0 $SIZE $PathToImage Where $SIZE is the size of the image file in bytes. $PathToImage is the absolute or relative path to the image file. My usual experience with "illegal instruction" is incompatible binary on the running system. Make sure that the binary, like mtd_debug or nandwrite or flash_erase are all ARM-compatible whether by:  Using the command "file" on the PC where the binary was cross-compiled. $ file flash_erase flash_erase: ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), for GNU/Linux 2.6.0, not stripped  Running it on the target with no arguments. # ./flash_erase Usage: flash_erase MTD-device [start] [cnt (# erase blocks)] [lock] flash_erase -h | --help *** Regards, Dave
Yes all those work in terms of showing usage, et. al. Even the nandtest works fully, just nanderase/nandwrite didn't. I gave what you said a try. And using those tools, it worked. Thank your coworker on my behalf, and thank you for relaying this information to me. In my case, I used: flash_erase /dev/mtd2 0 3947 As output from mtd_debug reported mtd.size = 64667648 (61M) and mtd.erasesize = 16384 (16K) so division of the two numbers resulted in 3947. Erased flash just fine, was able to reboot and get unable to mount root filesystem, which is a very good sign that it actually worked. Proceeding to reload my rootfs image through USB, did it one more time, this time with the image on hand on a usb stick. I was able to write this new version (added a file called "msg" to the root filesystem with the text "it worked") rebooting after loading it on with mtd_debug write, and the file was there, where it wasn't on the previous image. Fantastic, I had been fighting with this for a few days now. I had, actually, started to redesign my firmware image format to allow for incremental updating just writing to flash (say if i was replacing busybox with a new version, just extract it over the running version) which was fine -- and it will be handy in the future to make a change to the web interface w/o having to reboot the device, just restart boa instead. Made it more versatile so that even this operation is still possible. I'm seriously pumped about this now. Again, thanks!
Forgot to mention, that your image has to be page aligned otherwise mtd_debug write will complain, and your system will not boot. Left that out of my previous message. My apologies.
Thanks for the feedback, I'll sort this away for when I start to play with things at this level. He was happy to help. Cheers, Dave
Ignore my previous posts, I'm not sure why i got the unable to mount root before, but it must have been a network communication problem (uboot was still set to boot off an nfs mount, which is actually where i made the yaffs2 image from, so the msg file was there anyway). This did not solve the problem. flash_erase works great, but mtd_write does not. I've tried not aligning it, aligning it to write size, aligning to erase size, still unable to mount the filesystem. Any other suggestions?
Update: flash_erase as I outlined earlier and stated later, works just fine. Doing a: nandwrite -p /dev/mtd2 <size of my image padded to 512 byte boundaries or even without> Also appears to succeed (got rid of the invalid instruction by building statically with an older toolchain), but unable to mount root as in my last post. However, after reloading an OLDER image on (I know it's an older image because I changed passwords in the later revisions), when logging in as root, it prompts me for a password, which is the behaviour of the new firmware image, even though I loaded the old one on through the menu in supervivi via usb. Confirmed it's the new image based on my /etc/version file, and the fact that df -h output on both the older image was 23.4 MB used, the new one 18.6 MB (yes, went down in size due to removal of some unused bits). This seems weird. I tripple checked that i was uploading my 0.99.0 image via usb each time after it failed to mount root, not my 0.99.1 image. This is frustrating, nandwrite appears to work, but is unable to mount root. I'm at my wits end here, need to get this going.
Ok, so here's the scoop. Finally got it working. Here's what I did step by step. And I'll include the full steps, including what happened which is why I had to do the first 4 steps. 1. Power on the system with NOR switch off. If it fails to boot up (LEDs fail to come on), continue to step 2, otherwise, skip to step 7. 2. Flip NOR switch back on, power on system. 3. Download vivi image 4. Download kernel image 5. Download root filesystem image (ALL THREE through USB) 6. Flip NOR switch off, powercycle. 7. From booted linux system, log in, config an IP if you need to transfer the file over the network. 8. cd /dev/shm 9. ftp your.host 10. Download your root filesystem image (i used yaffs2, others may work) 11. Ensure that you have mtd-tools on the existing image, or else be prepared to transfer those as well over. 12. If you had to transfer flash_erase and mtd_debug, ensure they are executable. 13. kill all running processes that aren't surrounded in 's from ps output except for your telnet/ssh connection. 14. mount -o remount,ro / 15. flash_erase /dev/mtd2 0 3947 (mtd_debug info /dev/mtd2 to get erase size, should be 16384. Divide the size in bytes, by the erase size, you'll get the value to exchange "3947" for. Though it will probably be 3947. See post by davef above for more details on this step). 16. mtd_debug write /dev/mtd2 0x250000 <size padded to write size> your_image. the size is the size of your image in bytes, padded to the write block size again that can be found in the output of mtd_debug info /dev/mtd2. This will be 512 on this board, but double check it to be sure. Take your file size into a calculator (ls -l will give you the file size of your image), divide it by the write block size, in my case, 512, round up to the nearest whole number. So if your value is 39452.35 round it always up regardless of what the decimal point is, even if it's .01, ensure that it's the next whole number bigger than the value your calculator returns back. So using the example, 39452.35, rounding it up gives you 39453. Multiply that number by 512, you'll get the size you need to pass to mtd_debug write). The 0x250000 mini2440 user manual as the start of the linux root filesystem. If yours is different, use the start of your root filesystem according to your partition map. 17. Reboot your system. Doing the above steps worked for me, if it doesn't work for you, be prepared to load the images back on. I suspect step 16 can be replaced using nandwrite -p -s 0x250000 your_image, but I did not test to verify. Feel free to test yourself.