Author: wmb Date: Tue Aug 31 21:15:48 2010 New Revision: 1945 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/1945
Log: OLPC XO-1.5 - Added keyjector script for XO-1.5, also tweaked XO-1 keyject.bth to reflect the latest olpc.bth .
Added: cpu/x86/pc/olpc/via/keyject.bth cpu/x86/pc/olpc/via/keyject.fth Modified: cpu/x86/pc/olpc/keyject.bth
Modified: cpu/x86/pc/olpc/keyject.bth ============================================================================== --- cpu/x86/pc/olpc/keyject.bth Mon Aug 30 20:31:04 2010 (r1944) +++ cpu/x86/pc/olpc/keyject.bth Tue Aug 31 21:15:48 2010 (r1945) @@ -14,6 +14,7 @@ in: ${BP}/dev/usb2/hcd/ohci/build/ohci.fc in: ${BP}/dev/usb2/hcd/ehci/build/ehci.fc in: ${BP}/dev/usb2/device/hub/build/hub.fc +in: ${BP}/dev/usb2/device/generic/build/generic.fc in: ${BP}/dev/usb2/device/net/build/usbnet.fc in: ${BP}/dev/usb2/device/serial/build/usbserial.fc in: ${BP}/dev/usb2/device/storage/build/usbstorage.fc @@ -21,7 +22,7 @@ in: ${BP}/dev/usb2/device/wlan/build/usb8388.fc in: ${BP}/dev/olpc/cafenand/build/cafenand.fc in: ${BP}/dev/olpc/cafecamera/build/cafecamera.fc -in: ${BP}/clients/memtest86/memtest +in: memtest in: ${BP}/clients/emacs/x86/emacs in: ${BP}/cpu/x86/pc/olpc/build/verify.img in: ${BP}/cpu/x86/pc/olpc/build/usb8388.bin @@ -68,7 +69,7 @@ fload ${BP}/cpu/x86/pc/olpc/loaddropins.fth " sourceurl" " sourceurl" $add-dropin
- " ${BP}/clients/memtest86/memtest" " memtest" $add-deflated-dropin + " memtest" " memtest" $add-deflated-dropin \ " ${BP}/cpu/x86/pc/olpc/images/olpc16EQima.wav" " splash" $add-deflated-dropin \ " ${BP}/cpu/x86/pc/olpc/images/Edge1-16k-EQ-Comp-Amp-ima.wav" " splash" $add-deflated-dropin " ${BP}/cpu/x86/pc/olpc/images/Edge1-8k-EQ-Comp-Amp-Short.wav" " splash" $add-deflated-dropin
Added: cpu/x86/pc/olpc/via/keyject.bth ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ cpu/x86/pc/olpc/via/keyject.bth Tue Aug 31 21:15:48 2010 (r1945) @@ -0,0 +1,258 @@ +purpose: Construct the Open Firmware module collection + +command: &builder &this +in: ${BP}/cpu/x86/pc/olpc/via/build/ec.img +in: ${BP}/cpu/x86/pc/olpc/via/build/romreset.di +in: ${BP}/cpu/x86/pc/olpc/via/build/romstart.di +in: ${BP}/cpu/x86/pc/olpc/via/build/resume.di +in: ${BP}/cpu/x86/pc/olpc/via/build/rmstart.img +in: ${BP}/cpu/x86/pc/olpc/via/build/paging.di +in: ${BP}/cpu/x86/pc/olpc/via/build/fw.dic +in: ${BP}/dev/mmc/sdhci/build/sdhci2.fc +in: ${BP}/dev/mmc/sdhci/build/sdhcixo.fc +in: ${BP}/dev/mmc/sdhci/build/sdmmc.fc +in: ${BP}/dev/mmc/sdhci/mv8686/build/mv8686.fc +in: ${BP}/dev/usb2/hcd/uhci/build/uhci.fc +in: ${BP}/dev/usb2/hcd/ehci/build/ehci.fc +in: ${BP}/dev/usb2/device/hub/build/hub.fc +in: ${BP}/dev/usb2/device/generic/build/generic.fc +in: ${BP}/dev/usb2/device/net/build/usbnet.fc +in: ${BP}/dev/usb2/device/serial/build/usbserial.fc +in: ${BP}/dev/usb2/device/storage/build/usbstorage.fc +in: ${BP}/dev/usb2/device/keyboard/build/usbkbd.fc +in: ${BP}/clients/memtest86/memtest +in: ${BP}/clients/emacs/x86/emacs +in: ${BP}/cpu/x86/pc/olpc/via/build/verify.img +in: ${BP}/dev/pci/build/pcibridg.fc +in: ${BP}/dev/ide/build/idehier.fc +\ in: ${BP}/dev/ide/build/leghier.fc +\ in: ${BP}/cpu/x86/pc/olpc/via/build/camera.fc +in: ${BP}/cpu/x86/pc/olpc/via/build/dsdt.aml +in: ${BP}/cpu/x86/pc/olpc/via/build/mcastnand.bin +in: ${BP}/dev/hdaudio/build/hdaudio.fc +in: sd8686.bin +in: testicons.bin +in: ${BP}/cpu/x86/pc/olpc/images/bigx.di +in: ${BP}/cpu/x86/pc/olpc/images/bigcheck.di +in: ${BP}/cpu/x86/pc/olpc/images/leds.di +in: ${BP}/cpu/x86/pc/olpc/images/ebook.di + +build-now + +fload ${BP}/cpu/x86/pc/olpc/via/fw-version.fth +macro: FW_MINOR 49z + +" macro: FW_VERSION Q3${FW_MAJOR}${FW_MINOR}" expand$ eval + +fload ${BP}/cpu/x86/pc/olpc/via/config.fth + +\ Always re-create the builton.fth file when we make a new rom.img +fload ${BP}/cpu/x86/pc/builton.bth +fload ${BP}/cpu/x86/pc/olpc/via/sourceurl.fth + +fload ${BP}/forth/lib/crc32.fth + +hex + +: pad-file ( location -- ) + ofd @ fsize + 2dup u< abort" The ROM image is too large" + ?do h# ff ofd @ fputc loop +; + +.( --- Saving as ) +" ${FW_VERSION}.rom" expand$ 2dup lower ( adr len ) +2dup type cr ( adr len ) +$new-file +[ifdef] xo-board + " ec.img" $add-file +[then] + + dropin-base rom-pa - pad-file + +[ifdef] coreboot-loaded + " romstart.di" $add-file +[else] + " romreset.di" $add-file +[then] + + " resume.di" $add-file + +\ Loads the set of drivers that is common to different output formats + + " paging.di" $add-file + " ${BP}/cpu/x86/build/inflate.bin" " inflate" $add-dropin + " fw.img" " firmware" $add-deflated-dropin +\ " fw.img" " firmware" $add-dropin + + " ${BP}/dev/usb2/hcd/uhci/build/uhci.fc" " class0c0300" $add-deflated-dropin + " ${BP}/dev/usb2/hcd/ehci/build/ehci.fc" " class0c0320" $add-deflated-dropin + " ${BP}/dev/usb2/device/hub/build/hub.fc" " usb,class9" $add-dropin + " ${BP}/dev/usb2/device/generic/build/generic.fc" " usbdevice" $add-deflated-dropin + " ${BP}/dev/usb2/device/net/build/usbnet.fc" " usbnet" $add-deflated-dropin + " ${BP}/dev/usb2/device/keyboard/build/usbkbd.fc" " usb,class3,1" $add-dropin + " ${BP}/dev/usb2/device/serial/build/usbserial.fc" " usbserial" $add-deflated-dropin + " ${BP}/dev/usb2/device/storage/build/usbstorage.fc" " usbstorage" $add-deflated-dropin +\ " mrv8686.bin" " mrv8686.bin" $add-deflated-dropin + +[ifdef] notdef + " ${BP}/dev/pci/build/pcibridg.fc" " class060400" $add-deflated-dropin +\ " ${BP}/dev/ide/build/leghier.fc" " class01018a" $add-deflated-dropin + " ${BP}/dev/ide/build/idehier.fc" " class01018f" $add-deflated-dropin +[then] +[ifdef] xo-board + " ${BP}/dev/mmc/sdhci/build/sdhcixo.fc" " class080501" $add-deflated-dropin +[then] +[ifdef] demo-board + " ${BP}/dev/mmc/sdhci/build/sdhci2.fc" " class080501" $add-deflated-dropin +[then] + " ${BP}/dev/mmc/sdhci/build/sdmmc.fc" " sdmmc" $add-deflated-dropin + " ${BP}/dev/mmc/sdhci/mv8686/build/mv8686.fc" " mv8686" $add-deflated-dropin + " sd8686_helper.bin" " helper_sd.bin" $add-deflated-dropin + " sd8686.bin" " sd8686.bin" $add-deflated-dropin + + " builton.fth" " probe-" $add-dropin + + " ${BP}/clients/emacs/x86/emacs" " emacs" $add-deflated-dropin + " ${BP}/clients/emacs/x86/emacs.rc" " emacs.rc" $add-deflated-dropin + " ${BP}/clients/emacs/emacs.hlp" " emacs.hlp" $add-deflated-dropin + + " ${BP}/ofw/fcode/memtest.fth" " memtest.fth" $add-deflated-dropin + + " ${BP}/dev/hdaudio/build/hdaudio.fc" " class040300" $add-deflated-dropin + + " ${BP}/ofw/inet/telnetd.fth" " telnetd" $add-deflated-dropin + +\ " ${BP}/cpu/x86/pc/olpc/images/warnings.565" " warnings.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/lightdot.565" " lightdot.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/yellowdot.565" " yellowdot.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/darkdot.565" " darkdot.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/lock.565" " lock.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/unlock.565" " unlock.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/plus.565" " plus.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/minus.565" " minus.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/x.565" " x.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/sad.565" " sad.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/bigdot.565" " bigdot.565" $add-deflated-dropin + + " ${BP}/cpu/x86/pc/olpc/images/check.565" " check.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/xogray.565" " xogray.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/ethernet.565" " ethernet.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/usbkey.565" " disk.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/wireless.565" " wlan.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/laptop.565" " int.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/sd.565" " ext.565" $add-deflated-dropin + + " ${BP}/cpu/x86/pc/olpc/DisplayEDID.raw" " edid" $add-deflated-dropin + + " ${BP}/ofw/termemu/15x30pc.psf" " font" $add-deflated-dropin +[ifdef] use-ega + " ${BP}/ofw/termemu/cp881-16.obf" " pcfont" $add-deflated-dropin +[then] + + " memtest" " memtest" $add-deflated-dropin + + " verify.img" " verify" $add-deflated-dropin + " os.public" " ospubkey" $add-dropin \ Incompressible + " fw.public" " fwpubkey" $add-dropin \ Incompressible + " fs.public" " fspubkey" $add-dropin \ Incompressible + " lease.public" " leasepubkey" $add-dropin \ Incompressible + " developer.public" " develpubkey" $add-dropin \ Incompressible + " sourceurl" " sourceurl" $add-dropin + + " ${BP}/cpu/x86/pc/olpc/images/Edge1-8k-EQ-Comp-Amp-Short.wav" " splash" $add-deflated-dropin + + " ${BP}/cpu/x86/pc/olpc/via/build/dsdt.aml" " dsdt" $add-deflated-dropin +\ " ${BP}/cpu/x86/pc/olpc/via/build/ssdt.aml" " ssdt" $add-deflated-dropin + + \ icons for mfg test gui + " testicons/play.565" " play.565" $add-deflated-dropin + " testicons/quit.565" " quit.565" $add-deflated-dropin + " testicons/cpu.565" " cpu.565" $add-deflated-dropin + " testicons/spi.565" " spi.565" $add-deflated-dropin + " testicons/ram.565" " ram.565" $add-deflated-dropin + " testicons/sdcard.565" " sdcard.565" $add-deflated-dropin + " testicons/keyboard.565" " keyboard.565" $add-deflated-dropin + " testicons/display.565" " display.565" $add-deflated-dropin + " testicons/touchpad.565" " touchpad.565" $add-deflated-dropin + " testicons/audio.565" " audio.565" $add-deflated-dropin + " testicons/usb.565" " usb.565" $add-deflated-dropin + " testicons/battery.565" " battery.565" $add-deflated-dropin + " testicons/camera.565" " camera.565" $add-deflated-dropin + " testicons/wifi.565" " wifi.565" $add-deflated-dropin + " testicons/clock.565" " clock.565" $add-deflated-dropin + " testicons/timer.565" " timer.565" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/images/bigx.di" $add-file + " ${BP}/cpu/x86/pc/olpc/images/bigcheck.di" $add-file + " ${BP}/cpu/x86/pc/olpc/images/leds.di" $add-file + " ${BP}/cpu/x86/pc/olpc/images/ebook.di" $add-file + + " ${BP}/cpu/x86/pc/olpc/via/build/nandblaster15_rx.bin" " nb15_rx" $add-deflated-dropin + " ${BP}/cpu/x86/pc/olpc/via/build/nandblaster_tx.bin" " nb_tx" $add-deflated-dropin + + " ${BP}/cpu/x86/pc/olpc/keyject.fth" " probe+" $add-deflated-dropin + " /space/bios-crypto/build/k2.public" " o1" $add-dropin \ Incompressible + " /space/bios-crypto/build/k2.public" " s1" $add-dropin + " /space/bios-crypto/build/k2.public" " d1" $add-dropin + " /space/bios-crypto/build/k2.public" " w1" $add-dropin + " /space/bios-crypto/build/k2.public" " a1" $add-dropin + +.( Dropin top is ) ofd @ fsize .x cr + +[ifdef] coreboot-loaded + /rom h# 10000 - pad-file \ coreboot init image must be in last FLASH block + " coreboot.img" $add-file +[else] + /rom h# 10000 - pad-file \ coreboot init image must be in last FLASH block +\ " cforth.img" $add-file \ Small Forth that runs from cache + + /rom h# 400 - pad-file \ rmstart image must start 0x400 from end + " rmstart.img" $add-file + +\ Insert the revision signature +/rom h# 40 - ofd @ fseek +h# 10 buffer: signature +signature h# 10 blank +" CL1" signature swap move +" ${FW_VERSION}" expand$ signature 6 + swap move +" Q3${FW_MAJOR}" expand$ signature d# 13 + swap move +signature h# 10 ofd @ fputs + +create sipbuf + cc c, 66 c, aa c, 55 c, 54 c, 24 c, 01 c, 88 c, + 77 c, 77 c, 10 c, 77 c, 14 c, 08 c, 77 c, 00 c, + 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, + 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, 00 c, +here sipbuf - constant /sipbuf + +/l buffer: crcbuf +/rom buffer: filebuf + +\ Via SIP ROM pointer +\ The address "-30" is fixed by the VX855 hardware. +\ We get to choose the address ffffffa0 +h# ffffff80 crcbuf l! +/rom h# 30 - ofd @ fseek +crcbuf /l ofd @ fputs + +/rom h# 80 - ofd @ fseek +sipbuf /sipbuf ofd @ fputs + +\ Read the entire image, compute the CRC, and store it h# 30 from the end +0 ofd @ fseek +filebuf /rom ofd @ fgets /rom <> abort" Can't read back image" +0 crctab filebuf /rom ($crc) crcbuf ! + +/rom h# 2c - ofd @ fseek +crcbuf /l ofd @ fputs +[then] + +ofd @ fclose + +\ Creating olpc.version serves two purposes: +\ a) It reports the firmware revision for use by external scripts +\ b) It provides an olpc.* artifact for the builder dependency management. + +writing keyject.version +" ${FW_VERSION}" expand$ 2dup lower ofd @ fputs +ofd @ fclose
Added: cpu/x86/pc/olpc/via/keyject.fth ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ cpu/x86/pc/olpc/via/keyject.fth Tue Aug 31 21:15:48 2010 (r1945) @@ -0,0 +1,265 @@ +purpose: Inject additional keys into manufacturing data +\ See license at end of file + +\ Search for !!! for things that may need to change for different deployments + +\ See HowItWorks near end of file for a description of the overall procedure + +\ !!! Re-implement this for each different deployment +: wrong-sku? ( -- flag ) + " P#" find-tag 0= if true exit then ( pn$ ) + + -null ( pn$' ) + 2dup " 1CL11ZP0KD6" $= if 2drop false exit then ( pn$ ) \ UY BYD LiFePO4 + 2dup " 1CL11ZP0KD7" $= if 2drop false exit then ( pn$ ) \ UY GP NiMH + 2dup " 1CL11ZP0KD9" $= if 2drop false exit then ( pn$ ) \ UY GP LiFePO4 +[ifdef] test-me + 2dup " 1CL11ZU0KDB" $= if 2drop false exit then ( pn$ ) \ US for testing +[then] + 2drop + + true +; + +\ !!! Change the date for each different deployment +: keyject-expired? ( -- flag ) " 20090401T000000Z" expired? ; + +\ !!! Change the key list for each different deployment +: new-key-list$ ( -- ) " o1 s1 d1 w1 a1" ; + +\ True if the all the requested tags are already present. +\ This prevents endless looping. +: already-injected? ( -- flag ) + new-key-list$ begin dup while ( $ ) + bl left-parse-string ( $' name$ ) + find-tag if ( $ value$ ) + 2drop ( $ ) + else ( $ ) + 2drop false exit + then ( $ ) + repeat ( $ ) + 2drop true +; + +: inject-key ( keyname$ -- ) + 2dup find-drop-in if ( keyname$ value$ ) + 2over ram-find-tag if ( keyname$ value$ oldvalue$ ) + 2 pick <> if ( keyname$ value$ oldvalue$ ) + 3drop ( keyname$ ) + ." Warning: inconsistent old tag length for " type cr ( ) + exit + then ( keyname$ value$ oldvalue-adr ) + >r 2tuck r> swap move ( valu$ keyname$ ) + green-letters + ." Replaced " type cr ( value$ ) + black-letters + else ( keyname$ value$ ) + 2swap ( value$ keyname$ ) + 2over 2over ( value$ keyname$ value$ keyname$ ) + ($add-tag) ( value$ keyname$ ) + green-letters + ." Added " type cr ( value$ ) + black-letters + then ( value$ ) + free-mem ( ) + else ( keyname$ ) + ." Warning: Can't find a dropin module for " type cr ( ) + then ( ) +; + +: inject-keys ( -- ) + get-mfg-data + new-key-list$ begin dup while ( $ ) + bl left-parse-string ( $' name$ ) + inject-key ( $ ) + repeat ( $ ) + 2drop ( ) + (put-mfg-data) ( ) +; + +: keyject-error ( msg$ -- ) + cr + red-letters ." Not injecting because: " type cr black-letters + cr + ." Will update firmware in 20 seconds" cr + d# 20,000 ms +; + +: do-keyject? ( -- flag ) + wrong-sku? if + " Wrong SKU" keyject-error + false exit + then + keyject-expired? if + " Date Expired" keyject-error + false exit + then + already-injected? if + " Keys Already Present" keyject-error + false exit + then + true +; + +false value new-firmware? +: got-firmware? ( dev$ -- flag ) + 2dup ." Looking for new bootfw2.zip on " type cr ( dev$ ) + dn-buf place ( ) + " \boot" pn-buf place ( ) + filesystem-present? 0= if false exit then ( ) + null$ cn-buf place ( ) + " bootfw2" bundle-present? 0= if false exit then ( ) + ." Found" cr ( ) + secure? if ( ) + load-crypto if ( ) + ." Crypto load failed" cr false exit ( ) + then ( ) + fwkey$ to pubkey$ ( ) + img$ sig$ fw-valid? 0= if ( ) + ." Bad signature" cr ( ) + false exit + then ( ) + then ( ) + img$ tuck flash-buf swap /flash min move ( len ) + ['] ?image-valid catch if ( x ) + ." Bad firmware image" cr ( x ) + drop false exit + then ( ) + ." Good image" cr ( ) + + true to new-firmware? ( ) + true ( true ) +; + +: get-new-firmware ( -- ) + all-devices$ begin dup while ( $ ) + bl left-parse-string ( $' dev$ ) + got-firmware? if 2drop exit then ( $ ) + repeat ( $ ) + 2drop +; + +: ac-connected? ( -- flag ) bat-status@ h# 10 and 0<> ; + +\ Empirically, a weak-but-present battery can present the "trickle charge" (80) +\ but not present the "present" bit (01). +: battery-present? ( -- flag ) bat-status@ h# 81 and 0<> ; + +\ Similarly, a weak-but-present battery can present the "trickle charge" (80) +\ but not present the "battery low" bit (04). +: battery-strong? ( -- flag ) bat-status@ h# 84 and 0= ; + +: wait-enough-power ( -- ) + ac-connected? 0= if + ." Please connect the AC adapter to continue..." + begin d# 100 ms ac-connected? until + cr + then + battery-present? 0= if + ." Please insert a well-charged battery to continue..." + begin d# 100 ms battery-present? until + cr + then + battery-strong? 0= if + ." The battery is low. Please insert a charged one to continue..." + begin d# 100 ms battery-present? battery-strong? and until + then +; + +\ Firmware is in flash-buf +: update-firmware ( -- ) + write-firmware + + ['] verify-firmware catch if + ." Verify failed. Retrying once" cr + spi-identify + write-firmware + verify-firmware + then +; + +: ?keyject ( -- ) + visible + green-letters cr ." Security Key Injector" cr cr black-letters + \ Get the new firmware first, so any security checks use the old keys + get-new-firmware + do-keyject? if + wait-enough-power + flash-write-enable + inject-keys + new-firmware? if update-firmware then + flash-write-disable \ Should reboot + else + \ If we can't update the firmware, don't touch the SPI FLASH, lest + \ we get into an infinite reboot cycle. + new-firmware? if + ." Updating firmware ..." cr + wait-enough-power + flash-write-enable + update-firmware + flash-write-disable \ Should reboot + then + then +; + +?keyject + +[ifdef] HowItWorks +OLPC signs bootfw.zip containing OFW image A and bootfw2.zip containing OFW image B. +* A is an OFW with additional keyjector functionality +* B is an ordinary OFW +Version number B > version number A. + +bootfw.zip and bootfw2.zip are presented to a deployment machine in the usual manner, +either on a USB key or as part of a signed OS image. + +On a deployment machine with firmware X (version X < version A): + +The deployment machine (with old firmware version X < A) +auto-reflashes itself with firmware A via the existing secure +reflash mechanism. + +1) Firmware A starts and chacks that: + + The SKU is for the intended deployment + + the date is before the keyjector expiration date + + The override keys are not already present +so it + ! Injects the new keys +then it + ! Reads bootfw2.zip, checks its signature, and reflashes with firmware B (version > A) + ! Reboots + +2) Firmware B starts, performs the normal fw update attempt step, +noticing that data.img (firmware A) is downrev, and proceeds to +boot normally. + +In step (1), on a non-UY SKU, or after the expiration date, +firmware A skips the keyjection step and instead goes straight +to the "reflash firmware B" step. + +In either case, the machine ends up with (normal) firmware B. +[then] + +\ LICENSE_BEGIN +\ Copyright (c) 2007 FirmWorks +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ +\ LICENSE_END
openfirmware@openfirmware.info