Author Topic: Angel, Zimage.bin, Mversions.bin And Crcs  (Read 2409 times)

iamasmith

  • Hero Member
  • *****
  • Posts: 1248
    • View Profile
Angel, Zimage.bin, Mversions.bin And Crcs
« on: March 29, 2005, 03:11:26 pm »
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
OpenBSD 4.2 -current on full 4Gb of SL-C3000
Microdrive replaced with 4Gb SanDisk Extreme III card

iamasmith

  • Hero Member
  • *****
  • Posts: 1248
    • View Profile
Angel, Zimage.bin, Mversions.bin And Crcs
« Reply #1 on: March 30, 2005, 07:34:45 am »
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
OpenBSD 4.2 -current on full 4Gb of SL-C3000
Microdrive replaced with 4Gb SanDisk Extreme III card

euroclie

  • Full Member
  • ***
  • Posts: 205
    • View Profile
    • http://
Angel, Zimage.bin, Mversions.bin And Crcs
« Reply #2 on: March 30, 2005, 09:54:30 am »
Quote
Fixing this is actually pretty straight forward and I now have an installer that correctly flashed the Kernel AND the other parts
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"...

Thanks for your hard work!
Patrick

Mickeyl

  • Hero Member
  • *****
  • Posts: 1495
    • View Profile
    • http://www.Vanille.de
Angel, Zimage.bin, Mversions.bin And Crcs
« Reply #3 on: March 30, 2005, 09:54:37 am »
Mind sharing your work with us?
Cheers,

Michael 'Mickey' Lauer | Embedded Linux Freelancer | www.Vanille-Media.de
Consider donating, if you like the software I contribute to.

iamasmith

  • Hero Member
  • *****
  • Posts: 1248
    • View Profile
Angel, Zimage.bin, Mversions.bin And Crcs
« Reply #4 on: March 30, 2005, 10:43:40 am »
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: [Select]
......
....
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: [Select]
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: [Select]
              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: [Select]
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
OpenBSD 4.2 -current on full 4Gb of SL-C3000
Microdrive replaced with 4Gb SanDisk Extreme III card

iamasmith

  • Hero Member
  • *****
  • Posts: 1248
    • View Profile
Angel, Zimage.bin, Mversions.bin And Crcs
« Reply #5 on: March 31, 2005, 03:05:52 am »
And finally the proper fix... this allows the ONESIZE parameter to be left as it was.

Change....
Code: [Select]
                       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.
« Last Edit: March 31, 2005, 03:16:46 am by iamasmith »
OpenBSD 4.2 -current on full 4Gb of SL-C3000
Microdrive replaced with 4Gb SanDisk Extreme III card