Unlocking NAND

Jeremy Tregunna
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.

Jeremy Tregunna
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.

davef
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.)

[1] 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

[2] 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.

[3] 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:

[1] 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

[2] 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

Jeremy Tregunna
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!

Jeremy Tregunna
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.

davef
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

Jeremy Tregunna
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?

Jeremy Tregunna
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.

Jeremy Tregunna
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.

Ross Dela Mata 09120606060
how to unlock reserve memory ram