\ OLPC Boot Script for updating the OS and OFW images d# NANDVER constant new-os-build# h# ROMVER constant new-fw-version# : fw-version# ( -- n ) h# ffff.ffc8 3 push-hex $number pop-base if 0 exit then ; ' . to .error \ Suppress fancy abort messages ' noop to load-started \ Suppress the load progress spinner ' noop to ?show-device \ Suppress the boot progress icons ' false to auto-boot? \ Suppress automatic booting after this finishes \ Some string construction tools d# 256 buffer: $consbuf : init$ ( -- $ ) 0 $consbuf c! $consbuf count ; \ Append end$ to start$ : $+ ( start$ end$ -- start$' ) 2swap drop 1- ( end$ 'start ) >r r@ $cat ( r: 'start ) r> count ; \ Determine the device specifier of the device from which we just booted : boot-device$ ( -- dev$ ) " /chosen" find-package drop ( phandle ) " bootpath" rot get-package-property drop ( path$ ) get-encoded-string ( path$' ) [char] \ split-string ( dev$ filename$ ) 2drop ( dev$ ) ; \ Update the NAND FLASH with a new OS image. [ifndef] os-build# \ Read the OS build number from the file /boot/olpc_build : os-build# ( -- n ) " nand:\boot\olpc_build" r/o open-file if ( fd ) drop 0 exit \ File not found then ( fd ) >r pad h# 10 r@ read-line ( len not-eof? err r: fd ) r> close-file drop ( len not-eof? err ) if 2drop 0 exit then ( len not-eof? ) drop pad swap ( adr len ) push-decimal $number pop-base if 0 exit then ( n ) ; [then] \ Constructs a string like "copy-nand /sd/disk:\boot\nand300.img" : copy-nand-cmd$ ( -- $ ) init$ ( $ ) " copy-nand " $+ ( $' ) boot-device$ $+ ( $' ) " \boot\nand" $+ ( $' ) push-decimal new-os-build# (.) pop-base $+ ( $' ) " .img" $+ ; : update-nand ( -- ) ." Checking existing OS image on NAND FLASH" cr ." Existing OS build is " os-build# .d cr os-build# new-os-build# < if ['] noop to show-progress cr ." Updating OS image on NAND FLASH from build " os-build# .d ." to build " new-os-build# .d cr copy-nand-cmd$ ['] eval catch ?dup if cr (.error) else cr ." Done" cr then \ Having rewritten the NAND FLASH, the JFFS2 node cache we created \ during up-to-date? is no longer valid. " dev /jffs2-file-system true to first-time? dend" eval else ." NAND image is already current; skipping update" cr then ; \ Update the firmware to the latest version \ Constructs a string like "flash /sd/disk:\boot\q2c01.rom" : flash-command$ ( -- adr len ) init$ ( $ ) " flash " $+ ( $' ) boot-device$ $+ ( $' ) " \boot\q2" $+ ( $' ) push-hex new-fw-version# (.) pop-base $+ ( $' ) " .rom" $+ ; : update-firmware ( -- ) ." Existing firmware version is q2" fw-version# . cr fw-version# new-fw-version# < if \ E.g. B14 cr ." Updating firmware from q" fw-version# .x ." to q" new-fw-version# .x cr flash-command$ ['] eval catch ?dup if cr (.error) then \ We only get here if the flash command failed; success powers off else ." Firmware is already current; skipping update" cr then ; : update-both ( -- ) update-nand update-firmware ." Remove the autoupdater media and power-cycle" cr quit ; update-both