OESF Portables Forum
General Forums => General Discussion => Topic started by: iamasmith 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
-
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
-
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!
-
Mind sharing your work with us?
-
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..
......
....
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...
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...
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...
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
-
And finally the proper fix... this allows the ONESIZE parameter to be left as it was.
Change....
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.