ts-7000
[Top] [All Lists]

[ts-7000] runtime kernel upgrades in on-board flash

To:
Subject: [ts-7000] runtime kernel upgrades in on-board flash
From: Christopher Friedt <>
Date: Tue, 09 May 2006 19:44:03 +0000
I'm not sure if anyone on the list has tried this as of yet, but I've
been looking for a way to replace the kernel in flash at runtime.

Presently, all of the Technologic documentation says that you need to
replace kernel images from the RedBoot command line. This grows to be a
bit cumbersome when boards are in production or operation because it
requires an immediate physical presence of a technician in the field,
just to type a few simple keystrokes. In many cases though, the boards 
will be at quite a distance from eachother, so direct interaction 
becomes impractical.

My strategy was this:

1) if the kernel is loaded into SDRAM, that means it is not XIP (execute
    in place). -- confirmed -- NAND flash is too slow for general
    execution... also, cat /proc/iomem shows it resides in RAM at
    runtime. Therefore the kernel section in flash must be writeable!
2) find out the proper flash 'partition' to write to
3) determine the exact offset to start writing from above partition
4) use the proper utility to write new kernel image to flash
5) reboot && verify that the kernel image was properly updated.

I haven't fully tested what I came up with yet because I wanted to ask 
if anyone else has attempted this, and if so, what parameters are 
important?

Lennert and / or Jessie, I am guessing that you probably know the answer 
to this, but I wanted to post for everyone else's benefit too.

Please keep in mind that I do not want anyone to try this on a mass 
scale until it's been confirmed to work, especially because the MTD 
people have dropped support for the 2.4 kernel.

One would _think_ that it would be possible to overwrite the kernel 
image (vmlinux) which exists in flash memory using the 'dd' command. For 
example,

dd if=zImage of=/dev/mtd/X obs=8 seek=<some_offset>

However, this will ONLY work if the write areas being addressed have 
zero bad blocks. Otherwise, since the NAND devices are sequential, there 
will be one block of data missing. Also, it assumes that the NAND device 
does not require a prior erase cycle.

NAND devices, which are increasingly cheaper to manufacture than NOR 
devices, are not gauranteed to have zero bad blocks upon shipment. 
Needless to say, assuming there are zero bad blocks is not the best idea.

The 'dd' utility does not currently take those considerations into 
account when writing to flash devices. Thus, the good folks at 
http://www.linux-mtd.infradead.org wrote up block dumping / writing 
utilities specifically to cover this gap (nanddump / nandwrite).

The nanddump / nandwrite, as well as a slew of other MTD utilities can 
be obtained from http://www.linux-mtd.infradead.org/source.html . You 
will need to use "git" unless you find a snapshot somewhere.

OK, SO - to re-image the kernel section in flash memory, it's a good 
idea to make sure that the zImage binary does not exceed the 'partition' 
size that RedBoot has allocated for it.

###################################################
#!/bin/sh
#
# upgrade_kernel_in_flash.sh
#
# Assume $1 is 'zImage'
# my actual kernel size was 0xCB7FF ... RedBoot says
# that the partition size is 0xCC000 so i assume that
# is the upper bound. 0xCC000 (hex) = 835,584 (dec)

allowed_size=835584

# Arbitrary, but mainly to prevent stupid mistakes
min_size=100000

img_size=`wc -c $1`

# Probably better to write a usage() function
if [ ! $# -eq 1 ] || [ "$1" == "--help" ]; then
   echo "Usage: $0 <filename>"
   exit 1
else
   if [ ! -f $1 ]; then
       echo "$1 is not a regular file"
       exit 2
   else
     if [ $img_size -ge $allowed_size ] ||
        [ $img_size -lt $min_size ]; then
       echo "$1 is > $allowed_size or < $min_size"
       exit 3
     else
       # go ahead and do a 'nandwrite' operation
       # (will fill in later)
       # exit $?
     fi
   fi
fi

###################################################

Next, to locate the kernel in flash memory, I did the following:

RedBoot> fis list
Name              FLASH addr  Mem addr    Length      Entry point
(reserved)        0x60000000  0x60000000  0x01D04000  0x00000000
RedBoot           0x61D04000  0x61D04000  0x00040000  0x00000000
vmlinux           0x61D44000  0x00218000  0x000CC000  0x00218000
RedBoot config    0x61FF8000  0x61FF8000  0x00001000  0x00000000
FIS directory     0x61FFC000  0x61FFC000  0x00004000  0x00000000

You should notice that the start address of the kernel image is
0x61D44000. This translates to a 0x40000 offset from the 'RedBoot' 
partition. Now on the board, if you check out

$ cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00004000 00004000 "TS-BOOTROM"
mtd1: 01d00000 00004000 "Linux"
mtd2: 002fc000 00004000 "RedBoot"

You'll notice that the RedBoot partition corresponds to /dev/mtd/2 (char 
device) which is subsequently related to /dev/mtdblock/2 (block device).

I also went a bit further than this for paranoia's sake, and performed a 
hexedit on the most recent kernel image that I had flashed my board 
with. The first several bytes of the kernel image were:

$ hexedit zImage
00000000   00 00 A0 E1  00 00 A0 E1  00 00 A0 E1  00 00 A0 E1
00000010   00 00 A0 E1  00 00 A0 E1  00 00 A0 E1  00 00 A0 E1
00000020   02 00 00 EA  18 28 6F 01  ...

Next, I NFS mounted my laptop's /usr/debian_root directory from the 
board and dumped the entire /dev/mtd/2 partition out to a file on my 
laptop's hard disk. Below, the -o option says to omit OOB (out of bound) 
data and the -f just specifies an output filename.

$ mount -t nfs 192.168.2.201:/usr/debian_root /mnt/nfs
$ nanddump -o -f /mnt/nfs/dev_mtd_2.bin /dev/mtd/2

After that, to make sure I had a matching memory location, I did a 
hexedit on the image i just wrote to my laptop.

$ hexedit /usr/debian_root/dev_mtd_2.bin
00000000   43 52 55 53  FD 03 00 EA  18 F0 9F E5  18 F0 9F E5  CRUS...
00000010   18 F0 9F E5  18 F0 9F E5  00 00 00 00  18 F0 9F E5
00000020   18 F0 9F E5  FC 0F 00 00  30 91 00 00  54 91 00 00
00000030   80 91 00 00  9C 91 00 00  00 00 00 00  B4 92 00 00
00000040   7C 92 00 00  00 00 00 00  00 00 00 00  00 00 00 00
00000050   00 00 00 00  00 00 00 00  00 00 00 00  00 00 ...

Obviously, I had some searching to do... so I used hexedit's built in 
hexa-search to look for a signature from my kernel image :) This just 
requires a '/' keystroke.

Hexa string to search: () 020000EA1828

and voila! I found the start point of my kernel (by hitting up a couple 
of times)!

...
00040000   00 00 A0 E1  00 00 A0 E1  00 00 A0 E1  00 00 A0 E1
00040010   00 00 A0 E1  00 00 A0 E1  00 00 A0 E1  00 00 A0 E1
00040020   02 00 00 EA  18 28 6F 01  ...

Sure enough, it was at the same 0x40000 byte offset from the 'RedBoot' 
partition, just like RedBoot said (duh!).

So, I updated the shell script from before. The -a option specifies 
automatic placement of OOB data. The -s option specifies an effective 
'seek' position to start at.

###################################################
...
          # go ahead and do a 'nandwrite' operation
          # kernel image should start at 0x40000
          # 0x40000 (hex) = 262144 (dec)
          nandwrite -a -s 262144 /dev/mtd/2
          exit $?
...
###################################################

I'm pretty ready to go here, but I wanted to see what everyone thought. 
Do I need any other options? The options available are below.

$ nandwrite --help
Usage: nandwrite [OPTION] MTD_DEVICE INPUTFILE
Writes to the specified MTD device.

   -a, --autoplace       Use auto oob layout
   -j, --jffs2           force jffs2 oob layout (legacy support)
   -y, --yaffs           force yaffs oob layout (legacy support)
   -f, --forcelegacy     force legacy support on autoplacement enabled 
mtd device
   -n, --noecc           write without ecc
   -o, --oob             image contains oob data
   -s addr, --start=addr set start address (default is 0)
   -p, --pad             pad to page size
   -b, --blockalign=1|2|4 set multiple of eraseblocks to align to
   -q, --quiet           don't display progress messages
       --help            display this help and exit
       --version         output version information and exit


Any and all suggestions would be very well appreciated from myself but 
hopefully others who find this useful.

~/Chris


------------------------ Yahoo! Groups Sponsor --------------------~--> 
You can search right from your browser? It's easy and it's free.  See how.
http://us.click.yahoo.com/_7bhrC/NGxNAA/yQLSAA/CFFolB/TM
--------------------------------------------------------------------~-> 

 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/ts-7000/

<*> To unsubscribe from this group, send an email to:
    

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



<Prev in Thread] Current Thread [Next in Thread>
  • [ts-7000] runtime kernel upgrades in on-board flash, Christopher Friedt <=
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU