Help - Search - Members - Calendar
Full Version: Angel, Zimage.bin, Mversions.bin And Crcs
OESF Portables Forum > General Forums > General Discussion
iamasmith
Hi,

I have been messing around with updater.sh scripts all day trying to make the tetsu special kernel install using a Sharp provided updater.sh.

Tracking through the updater.sh I can see that it chops of the last 16 characters of the zImage before flashing it.. so I padded it with the 16 characters off an original Sharp image... this doesn't work.

The one version of updater that WILL flash a working kernel from this zImage seems to miss out the verchg commands that manipulate the version block (also this gets written off the contents of mversions.bin).

If I flash with ANY version of updater.sh other than the one that misses out the verchg commands then I get a bricked Zaurus... absolutely no life on standard boot.

What I'm wondering here is about the misterious 2 bytes at the end of this 16 bit block... this looks like a CRC to me and I think that because I'm supplying a valid CRC then the Z is using that information and determining that the zImage is invalid..

I could take the PDAXROM route and append 16 NULL characters to the Kernel which wouldn't match anything in the mversion block but I think its a good idea to create a REAL CRC if possible.

Does anyone really know what the CRC algorythm is for this? could it possibly by the CCITT 16 bit CRC?

Anyone have any documentation on Angel Bootloader (Intel White Angel) that could confirm this?

- Andy
iamasmith
OK, found the answer. The SL-C3000 doesn't give a hoot about the CRC.. what seems to be important is the logic of writing the Kernel that seems to be somewhat flawed in the updater.sh that Sharp issue with the upgrade.

The script seems like it should chop the kernel up into regular sized blocks and program these one at a time to the flash. It, however, seems to be writing these blocks with the full file size rather than the block size.. it may just be lucky that the shipped zImage.bin falls on an even boundary and that the nandflash tool actually flashes the complete image before it fails but this doesn't go for the tetsu Kernel.

Fixing this is actually pretty straight forward and I now have an installer that correctly flashed the Kernel AND the other parts smile.gif
euroclie
QUOTE(iamasmith @ Mar 30 2005, 02:34 PM)
Fixing this is actually pretty straight forward and I now have an installer that correctly flashed the Kernel AND the other parts smile.gif

Cool! I never like to "jump in the dark" whenever I reflash a PDA, so having that kind of knowledge is really very valuable to avoid doing too much "black magic"... wink.gif

Thanks for your hard work! biggrin.gif
Mickeyl
Mind sharing your work with us?
iamasmith
Sure,

ALERT: Long response...

As I said I WILL write up ALL my findings completely at some other time.

Firstly one correction. The bcut command does NOT cut 16 bytes off the zImage.bin file or the initrd.bin. It extracts the 16 byte region to get the minor and major version info sections from which the script uses to program the version information into those flash regions... kinda makes you wonder why they ship an mversion.bin file then doesn't it !

Anyway I won't bore you with the whole decoded script.. here's the highlights..

Firstly unmodified..
CODE
......
....
for TARGETFILE in zImage.bin zimage.bin ZIMAGE.BIN initrd.bin INITRD.BIN mversion.bin MVERSION.BIN
do
    if [ -e $TARGETFILE ]
    then
 rm -f $TMPPATH/*.bin > /dev/null 2>&1
 DATASIZE=`wc -c $TARGETFILE`
 DATASIZE=`echo $DATASIZE | cut -d' ' -f1`

 #echo $TARGETFILE':'$DATASIZE'bytes'
 TARGETTYPE=Invalid
 case "$TARGETFILE" in
 zImage.bin) TARGETTYPE=Kernel;;
 zimage.bin) TARGETTYPE=Kernel;;
 ZIMAGE.BIN) TARGETTYPE=Kernel;;
 initrd.bin) TARGETTYPE=RoFs;;
...... then goes into a swicth statemen based upon the TARGETTYPE
........
 case "$TARGETTYPE" in
 Kernel)
     if [ $WFLG_KERNEL != 0 ]
     then
   continue
     fi
     WFLG_KERNEL=1
     echo 'kernel'
     ISLOGICAL=1
     MODULEID=5
     MODULESIZE=0x13C000
     ADDR=`dc 0xE0000`
     ISFORMATTED=1
     DATAPOS=0
     ONESIZE=524288
     HDTOP=`expr $DATASIZE - 16`
     /sbin/bcut -a $HDTOP -s 16 -o $TMPHEAD $TARGETFILE
 ;;
.... The ONESIZE is used to control the flash programming size.... the logic error is not here but
.... this is where I fixed it.... ISLOGICAL is used later in the programming section to select the
... nandlogical method of flash programming.. you can also see the use of the bcut command that
... extracts the version information into the temporary file called $TMPHEAD
....
.... now the main grunt loop...
#loop
 while [ $DATAPOS -lt $DATASIZE ]
 do
     #data create
     bcut -a $DATAPOS -s $ONESIZE -o $TMPDATA $TARGETFILE
     TMPSIZE=`wc -c $TMPDATA`
     TMPSIZE=`echo $TMPSIZE | cut -d' ' -f1`
     DATAPOS=`expr $DATAPOS + $TMPSIZE`

     #handle data file
     #echo 'ADDR='$ADDR
     #echo 'SIZE='$TMPSIZE
     if [ $ISLOGICAL = 0 ]
     then
   next_addr=`/sbin/nandcp -a $ADDR $TMPDATA $TARGET_MTD  2>/dev/null | fgrep "mtd address" | cut -d- -f2 | cut -d\( -f1`
   if [ "$next_addr" = "" ]; then
       echo "ERROR:flash write"
       rm $TMPDATA > /dev/null 2>&1
       RESULT=3
       break;
   fi
   ADDR=$next_addr
     else
   /sbin/nandlogical $LOGOCAL_MTD WRITE $ADDR $DATASIZE $TMPDATA > /dev/null 2>&1
.... and HERE is where the logic error is... that $DATASIZE element is specifying the size of the
... block to write... DATASIZE is actually still set to the complete file size !
.....
   ADDR=`expr $ADDR + $TMPSIZE`
     fi

     rm $TMPDATA > /dev/null 2>&1

     #progress
     SPNUM=0
     while [ $SPNUM -lt $PROGSTEP ]
     do
   echo -n '.'
   SPNUM=`expr $SPNUM + 1`
     done
 done


So I took a dummy copy of the scripts, preprended some echo statements to some key lined and rewrote bcut using head and tail commands and ran through the script.... firstly unmodified...

CODE
kernel

0%                      100%
bcut -a 0 -s 524288 -o ./t zImage.bin
/sbin/nandlogical /dev/mtd1 WRITE 917504 1294336 ./t
bcut -a 524288 -s 524288 -o ./t zImage.bin
/sbin/nandlogical /dev/mtd1 WRITE 1441792 1294336 ./t
bcut -a 1048576 -s 524288 -o ./t zImage.bin
/sbin/nandlogical /dev/mtd1 WRITE 1966080 1294336 ./t

Success!


Note the flash block size is actually showing the whole file size... the nandlogical program increment actually does increase by the ONESTEP value size (524288), however, it's writing too much on each block operation and the last one is CLEARLY out of range.

So a simple modification to the Kernel switch case block...
CODE
              case "$TARGETTYPE" in
               Kernel)
                       if [ $WFLG_KERNEL != 0 ]
                       then
                               continue
                       fi
                       WFLG_KERNEL=1
                       echo 'kernel'
                       ISLOGICAL=1
                       MODULEID=5
                       MODULESIZE=0x13C000
                       ADDR=`dc 0xE0000`
                       ISFORMATTED=1
                       DATAPOS=0
                       ONESIZE=$DATASIZE
                       HDTOP=`expr $DATASIZE - 16`
                       /sbin/bcut -a $HDTOP -s 16 -o $TMPHEAD $TARGETFILE
                      ;;


Yields the following behaviour...

CODE
kernel

0%                      100%
bcut -a 0 -s 1294336 -o ./t zImage.bin
/sbin/nandlogical /dev/mtd1 WRITE 917504 1294336 ./t

Success!


This gets the flash programming done in one nandflash operation. I'm assuming that this is a safe operation because I have another version of updater.sh called updater.sh.c3000 from the Sharp website which programs the zImage region in one swoop (but ONLY does zImage and not the other bits).

Regards,

Andy
iamasmith
And finally the proper fix... this allows the ONESIZE parameter to be left as it was.

Change....
CODE
                       TMPSIZE=`wc -c $TMPDATA`
                       TMPSIZE=`echo $TMPSIZE | cut -d' ' -f1`
                       DATAPOS=`expr $DATAPOS + $TMPSIZE`

                       #handle data file
                       #echo 'ADDR='$ADDR
                       #echo 'SIZE='$TMPSIZE
                       if [ $ISLOGICAL = 0 ]
                       then
                               next_addr=`/sbin/nandcp -a $ADDR $TMPDATA $TARGET_MTD  2>/dev/null | fgrep "mtd address" | cut -d- -f2 | cut -d\( -f1`
                               if [ "$next_addr" = "" ]; then
                                       echo "ERROR:flash write"
                                       rm $TMPDATA > /dev/null 2>&1
                                       RESULT=3
                                       break;
                               fi
                               ADDR=$next_addr
                       else
                               # /sbin/nandlogical $LOGOCAL_MTD WRITE $ADDR $DATASIZE.... original
                               /sbin/nandlogical $LOGOCAL_MTD WRITE $ADDR $TMPSIZE $TMPDATA > /dev/null 2>&1


There.. that's a cleaner fix and properly implements the block programming using nandflash. smile.gif
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2019 Invision Power Services, Inc.