commit 56d2c574d1b7506f7772c027bf09e681de4a38ec Author: Clint Savage Date: Mon Dec 5 00:51:46 2011 -0600 srpm imported for GoOSe Linux 6.0 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ee86d42 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +yaboot-1.3.14.tar.gz diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e3a61a8 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +# This makefile is downloading any file found in +# the 'sources' file already existing in this directory +# and validating the sha256sum of the archive against it. +NAME := yaboot + +define find-common-dir +for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then echo "$$d"; break ; fi ; done +endef +COMMON_DIR := $(shell $(find-common-dir)) + +include $(COMMON_DIR)/Makefile.common + +SOURCEFILES := $(shell cat sources 2>/dev/null | awk '{ print $$2 }' | awk -F'*' '{ print $$2 }') + +sources: $(SOURCEFILES) + +$(SOURCEFILES): + @for sourcefile in $(SOURCEFILES); do \ + $(CLIENT) $(LOOKASIDE_URI)/$(NAME)/$${sourcefile}; \ + done + + sha256sum -c sources || ( echo 'SHA256 check failed' && rm $(SOURCEFILES); exit 1 ) + +clean: + rm $(SOURCEFILES) diff --git a/efika.forth b/efika.forth new file mode 100644 index 0000000..786212e --- /dev/null +++ b/efika.forth @@ -0,0 +1,336 @@ +\ FORTH + +." Efika 5200B Device Tree Supplement 20071114" cr +." (c) 2007 Genesi USA, Inc." cr +." http://www.powerdeveloper.org/ for support" cr cr + +\ headerless + +s" /openprom" find-device + d# 20071114 encode-int s" device-tree-version" property +device-end + +s" /builtin/ata" find-device + s" mpc5200-ata" encode-string + s" mpc5200b-ata" encode-string encode+ + s" compatible" property +device-end + +s" /builtin/sound" find-device + s" mpc5200-psc-ac97" encode-string + s" mpc5200b-psc-ac97" encode-string encode+ + s" compatible" property + + 0x2 encode-int + 0x2 encode-int encode+ + 0x3 encode-int encode+ + s" interrupts" property + + \ Audio is on PSC2, just for informational purposes + 1 encode-int s" cell-index" property +device-end + +\ Quick test to see if AC97 is enabled +0xf0000b00 dup dup l@ 0x20 and +0= if + ." Enabling AC97" cr + dup l@ 0x20 or + swap l! +else + drop +then + +\ SRAM compatibles +s" /builtin/sram" find-device + s" mpc5200-sram" encode-string + s" mpc5200b-sram" encode-string encode+ + s" compatible" property + + s" sram" device-type \ this is a contentious one +device-end + +\ PIC compatibles +s" /builtin/pic" find-device + s" mpc5200-pic" encode-string + s" mpc5200b-pic" encode-string encode+ + s" compatible" property +device-end + +\ Serial compatibles. Also fix cell-index and port-number as per bindings +s" /builtin/serial" find-device + s" mpc5200-psc-uart" encode-string + s" mpc5200b-psc-uart" encode-string encode+ + s" compatible" property + + \ Serial port is PSC1 for informational purposes, Linux 0-indexes it + 0 encode-int s" cell-index" property + \ Since this is the main, always there, preferred serial port.. + 0 encode-int s" port-number" property +device-end + +\ Ethernet compatibles +s" /builtin/ethernet" find-device + s" mpc5200-fec" encode-string + s" mpc5200b-fec" encode-string encode+ + s" compatible" property +device-end + +\ BestComm compatibles, interrupt mess +s" /builtin/bestcomm" find-device + s" mpc5200-bestcomm" encode-string + s" mpc5200b-bestcomm" encode-string + encode+ + s" compatible" property + + \ make 16 interrupt property in a batch. We have to do the first one by + \ hand simply because of the way encode+ works. + + 0x3 encode-int 0x0 encode-int 0x3 encode-int encode+ encode+ + 0x10 1 do + 0x3 encode-int encode+ i encode-int encode+ 0x3 encode-int encode+ + loop + + \ now we can store the damn thing + s" interrupts" property +device-end + +\ New USB binding - change one of the numbers here to disable it for older kernels +\ as this is a destructive change +0 1 = if +s" /builtin/usb" find-device + s" usb-ohci" device-type + s" " encode-string s" big-endian" property + + s" mpc5200-ohci" encode-string + s" mpc5200-usb-ohci" encode-string encode+ + s" compatible" property +device-end +then + +\ Go into the root node and kill off any mention of CHRP +s" /" find-device + s" efika" device-type + s" Efika 5200B" encode-string s" CODEGEN,board" property + s" Efika 5200B PowerPC System" encode-string s" CODEGEN,description" property +device-end + +\ Fix the /builtin device-type for Linux +s" /builtin" find-device + s" soc" device-type +device-end + +\ ADDING NEW ENTRIES TO THE DEVICE TREE +\ +\ Clock Distribution Module - need this to change baud rates etc. and turn off +\ clocks for power management. Useful little thing. Needs an entry to find the +\ address without guessing (in case they change it in the 512X) + +\ Clock Distribution Module +." Adding Clock Distribution Module" cr + +s" /builtin" find-device +new-device + " cdm" 2dup device-name device-type + " MPC52xx Clock Distribution Module" encode-string " .description" property + 0xf0000200 0x38 reg + + " mpc5200-cdm" encode-string + " mpc5200b-cdm" encode-string + encode+ + " compatible" property + +finish-device + +\ GPIO (Simple) Module +." Adding Simple GPIO Module" cr + +s" /builtin" find-device +new-device + s" gpio" 2dup device-name device-type + s" MPC52xx Simple GPIO" encode-string s" .description" property + 0xf0000b00 0x40 reg + + s" mpc5200-gpio" encode-string + s" mpc5200b-gpio" encode-string encode+ + s" compatible" property + + 0x10000000 encode-int s" gpio-mask" property + + 0x1 encode-int + 0x7 encode-int + 0x3 encode-int + encode+ encode+ + s" interrupts" property +finish-device + +\ GPIO (Wakeup) Module +." Adding Wakeup GPIO Module" cr + +s" /builtin" find-device +new-device + s" gpio-wkup" 2dup device-name device-type + s" MPC52xx Wakeup GPIO" encode-string s" .description" property + 0xf0000c00 0x28 reg + + s" mpc5200-gpio-wkup" encode-string + s" mpc5200b-gpio-wkup" encode-string + encode+ + s" compatible" property + + 0x30000000 encode-int s" gpio-mask" property + + 0x1 encode-int + 0x8 encode-int encode+ + 0x3 encode-int encode+ + 0x1 encode-int encode+ + 0x3 encode-int encode+ + 0x3 encode-int encode+ + s" interrupts" property +finish-device + +\ +\ High resolution (General Purpose and Slice) Timers +\ +\ We ignore slice timer 0 since critical interrupt handling in Linux +\ is curiously missing +." Adding Slice Timer 1" cr + +s" /builtin" find-device +new-device + s" slt" 2dup device-name device-type + s" MPC52xx Slice Timer 1" encode-string " .description" property + 0xf0000710 0x10 reg + + s" mpc5200-slt" encode-string + s" mpc5200b-slt" encode-string + encode+ + s" compatible" property + + 1 encode-int " cell-index" property + + \ The interrupt listed here is probably wrong + 0x1 encode-int + 0x0 encode-int encode+ + 0x3 encode-int encode+ + s" interrupts" property +finish-device + +\ Add all the GPTs to the device-tree +\ : gpt-add ( gpt-id -- ) +\ depth +\ 1 > if +8 0 do i + dup 7 <= if + dup + 0x9 + + swap dup + 0x10 * + 0xf0000600 + + swap dup + + ." Adding General Purpose Timer " .d cr + + s" /builtin" find-device + new-device + + s" gpt" 2dup device-name device-type + swap 0x10 reg + + encode-int s" cell-index" property + + s" MPC52xx General Purpose Timer X" + 2dup + 1 - \ get the character position of the X + 0x30 i + swap c! \ store ascii character of timer number + encode-string s" .description" property + + s" mpc5200-gpt" encode-string + s" mpc5200b-gpt" encode-string encode+ + s" fsl,mpc5200-gpt" encode-string encode+ + s" fsl,mpc5200b-gpt" encode-string encode+ + s" compatible" property + + 0x1 encode-int + 2 pick encode-int encode+ + 0x3 encode-int encode+ + s" interrupts" property + + finish-device + then +loop +\ then +\ ; + +\ Add watchdog marker to GPT0 +s" /builtin/gpt@f0000600" find-device + s" " encode-string s" has-wdt" property + s" " encode-string s" fsl,has-wdt" property +device-end + +\ PHY for ethernet. Thanks to Domen Puncer for this. +." Adding Ethernet PHY" cr + +s" /builtin" find-device +new-device + 1 encode-int s" #address-cells" property + 0 encode-int s" #size-cells" property + s" mdio" 2dup device-name device-type + s" mpc5200b-fec-phy" encode-string s" compatible" property + 0xf0003000 0x400 reg + + 0x2 encode-int + 0x5 encode-int encode+ + 0x3 encode-int encode+ + s" interrupts" property + + new-device + s" ethernet-phy" 2dup device-name device-type + 0x10 encode-int s" reg" property + + my-self \ save our phandle to stack + ihandle>phandle + finish-device +finish-device + +s" /builtin/ethernet" find-device + encode-int \ phy's phandle + s" phy-handle" property +device-end + +\ +\ HERE BE DRAGONS + +\ SDRAM Controller (needed to enter deep sleep and turn off RAM clocks) +." Adding SDRAM Controller" cr + +s" /builtin" find-device +new-device + s" sdram" device-name + s" memory-controller" device-type + + 0xf0000100 0x10 reg + + s" MPC52xx SDRAM Memory Controller" encode-string s" .description" property + + s" mpc5200b-sdram" encode-string + s" mpc5200-sdram" encode-string encode+ + s" compatible" property +finish-device + +\ XLB Arbiter (pipeline/bestcomm stuff enabled here) +." Adding XLB Arbiter" cr + +s" /builtin" find-device +new-device + s" xlb" 2dup device-name device-type + + 0xf0001f00 0x100 reg + + s" MPC52xx XLB Arbiter" encode-string s" .description" property + + s" mpc5200-xlb" encode-string + s" mpc5200b-xlb" encode-string encode+ + s" compatible" property +finish-device + +\ Optionally uncomment and boot your Linux +\ s" hd:0 vmlinuz console= blah=" $boot diff --git a/sources b/sources new file mode 100644 index 0000000..6a8421c --- /dev/null +++ b/sources @@ -0,0 +1 @@ +b1b0ddc798e332dc03065bac871b05f700b6f8383951a05dee68a7438f644933 *yaboot-1.3.14.tar.gz diff --git a/yaboot-1.3.10-configfile.patch b/yaboot-1.3.10-configfile.patch new file mode 100644 index 0000000..2b3b0b1 --- /dev/null +++ b/yaboot-1.3.10-configfile.patch @@ -0,0 +1,27 @@ +--- yaboot-1.3.10/ybin/yabootconfig.configfile 2003-06-19 17:33:50.000000000 -0400 ++++ yaboot-1.3.10/ybin/yabootconfig 2003-06-19 17:39:26.000000000 -0400 +@@ -103,6 +103,7 @@ + default: determined from {chroot}/etc/fstab + -b, --boot set bootstrap partition, Example: /dev/hda2 + default: first type: Apple_Bootstrap partition ++ -C, --config set config file name (Example: /etc/yaboot.conf) + --kernel-args add an append= line with specified arguments + -q, --quiet don't ask any questions/confirmation + --noinstall don't automatically run mkofboot +@@ -330,6 +331,16 @@ + exit 1 + fi + ;; ++ -C|--config) ++ if [ -n "$2" ]; then ++ CONFIG="$2" ++ shift 2 ++ else ++ echo 1>&2 "$PRG: option requires an argument $1" ++ echo 1>&2 "Try \`$PRG --help' for more information." ++ exit 1 ++ fi ++ ;; + -q|--quiet) + QUIET=1 + shift 1 diff --git a/yaboot-1.3.10-ext3.patch b/yaboot-1.3.10-ext3.patch new file mode 100644 index 0000000..af6fc15 --- /dev/null +++ b/yaboot-1.3.10-ext3.patch @@ -0,0 +1,11 @@ +--- yaboot-1.3.10/second/fs_ext2.c.ext3 2003-04-09 21:38:48.000000000 -0400 ++++ yaboot-1.3.10/second/fs_ext2.c 2003-04-09 21:40:32.000000000 -0400 +@@ -189,7 +189,7 @@ + ofopened = 1; + + /* Open the ext2 filesystem */ +- result = ext2fs_open (buffer, EXT2_FLAG_RW, 0, 0, linux_io_manager, &fs); ++ result = ext2fs_open (buffer, EXT2_FLAG_DIRTY, 0, 0, linux_io_manager, &fs); + if (result) { + + if(result == EXT2_ET_BAD_MAGIC) diff --git a/yaboot-1.3.10-parted.patch b/yaboot-1.3.10-parted.patch new file mode 100644 index 0000000..815f93b --- /dev/null +++ b/yaboot-1.3.10-parted.patch @@ -0,0 +1,29 @@ +--- yaboot-1.3.10/ybin/yabootconfig~ 2004-04-20 16:20:13.619375616 -0400 ++++ yaboot-1.3.10/ybin/yabootconfig 2004-04-20 16:32:40.519829488 -0400 +@@ -160,6 +160,8 @@ + FDISK=mac-fdisk + elif (command -v pdisk > /dev/null 2>&1) ; then + FDISK=pdisk ++ elif (command -v parted > /dev/null 2>&1) ; then ++ FDISK=parted + else + echo 1>&2 "$PRG: Unable to locate mac-fdisk" + return 1 +@@ -209,9 +211,16 @@ + BOOT="${DISK}${BOOT}" + fi + debug "BOOT after fixup: $BOOT\n" +- else ++ elif [ "$FDISK" = mac-fdisk ] ; then + BOOT="$(v=`$FDISK -l "$DISK" 2>/dev/null | grep '\'` ; echo ${v%%[ ]*})" + debug "BOOT=$BOOT\n" ++ else ++ BOOT="$(v=`$FDISK "$DISK" print 2>/dev/null | grep 'bootstrap'` ; echo ${v%%[ ]*})" ++ debug "BOOT before fixup: $BOOT\n" ++ if [ -n "$BOOT" ] ; then ++ BOOT="${DISK}${BOOT}" ++ fi ++ debug "BOOT after fixup: $BOOT\n" + fi + if [ -z "$BOOT" ] ; then + echo 1>&2 "$PRG: Unable to locate bootstrap partition on $DISK..." diff --git a/yaboot-1.3.10-proddiscover.patch b/yaboot-1.3.10-proddiscover.patch new file mode 100644 index 0000000..a28e57e --- /dev/null +++ b/yaboot-1.3.10-proddiscover.patch @@ -0,0 +1,59 @@ +--- yaboot-1.3.10/first/ofboot.name 2003-04-09 21:29:29.000000000 -0400 ++++ yaboot-1.3.10/first/ofboot 2003-04-09 21:29:55.000000000 -0400 +@@ -86,6 +86,13 @@ + MENU=1 + fi + ++if [ -f /etc/redhat-release ]; then ++ PRODUCT=`sed "s/ release.*//g" /etc/redhat-release` ++else ++ PRODUCT="PowerPC GNU/Linux" ++fi ++ ++ + ## create the variables. + ## + ## OSNAME="$1" +@@ -102,7 +109,7 @@ + [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "$PRG: DEBUG: file1: $5\n" + [ "$COUNT" = "$OSNUM" ] && c="." + BTYA=": boot$1 \" Loading second stage bootstrap...\" .printf 100 ms load-base release-load-area \" ${4}${5}\" \$boot ;" +- MENUYA="\" Press $3 for Red Hat Linux${c-,}\"(0d 0a)\" .printf" ++ MENUYA="\" Press $3 for $PRODUCT${c-,}\"(0d 0a)\" .printf" + GETYA=" ascii $3 of \" $3 \"(0d 0a)\" .printf boot$1 endof" + shift 5 + COUNT="$(($COUNT + 1))" +@@ -315,7 +322,7 @@ + MacRISC MacRISC3 MacRISC4 + + +-Red Hat Linux First Stage Bootstrap ++$PRODUCT First Stage Bootstrap + + + : .printf fb8-write drop ; +@@ -336,7 +343,7 @@ + $BGCOLOR to background-color + \" \"(0C)\" .printf + +-\" First Stage Red Hat Linux Bootstrap\"(0d 0a)\" .printf ++\" First Stage $PRODUCT Bootstrap\"(0d 0a)\" .printf + \" \"(0d 0a)\" .printf + $MENUOPTS + \" \"(0d 0a)\" .printf +--- yaboot-1.3.10/ybin/yabootconfig.name 2003-04-09 21:24:20.000000000 -0400 ++++ yaboot-1.3.10/ybin/yabootconfig 2003-04-09 21:27:07.000000000 -0400 +@@ -700,7 +700,12 @@ + ENABLENETBOOT="enablenetboot\n" + fi + +-MESG='"Welcome to Red Hat Linux!\\nHit for boot options.\\n\\n"' ++if [ -f /etc/redhat-release ]; then ++ PRODUCT=`sed "s/ release.*//g" /etc/redhat-release` ++else ++ PRODUCT="PowerPC GNU/Linux" ++fi ++MESG="\"Welcome to $PRODUCT!\\nHit for boot options.\\n\\n\"" + + ## generate global section of yaboot.conf + GLOBAL="boot=${BOOT}${DEVICE:-} diff --git a/yaboot-1.3.10-sbindir.patch b/yaboot-1.3.10-sbindir.patch new file mode 100644 index 0000000..f16b276 --- /dev/null +++ b/yaboot-1.3.10-sbindir.patch @@ -0,0 +1,51 @@ +--- yaboot-1.3.10/Makefile.sbindir 2003-04-28 18:14:43.000000000 -0400 ++++ yaboot-1.3.10/Makefile 2003-04-28 18:15:44.000000000 -0400 +@@ -9,6 +9,7 @@ + ROOT = + PREFIX = usr/local + MANDIR = man ++SBINDIR= ${PREFIX}/sbin + # command used to get root (needed for tarball creation) + GETROOT = fakeroot + +@@ -179,7 +180,7 @@ + + install: all strip + install -d -m 0755 ${ROOT}/etc/ +- install -d -m 0755 ${ROOT}/${PREFIX}/sbin/ ++ install -d -m 0755 ${ROOT}/${SBINDIR} + install -d -m 0755 ${ROOT}/${PREFIX}/lib + install -d -m 0755 ${ROOT}/${PREFIX}/lib/yaboot + install -d -m 0755 ${ROOT}/${PREFIX}/${MANDIR}/man5/ +@@ -187,11 +188,11 @@ + install -m 0644 second/yaboot ${ROOT}/$(PREFIX)/lib/yaboot + install -m 0755 util/addnote ${ROOT}/${PREFIX}/lib/yaboot/addnote + install -m 0644 first/ofboot ${ROOT}/${PREFIX}/lib/yaboot/ofboot +- install -m 0755 ybin/ofpath ${ROOT}/${PREFIX}/sbin/ofpath +- install -m 0755 ybin/ybin ${ROOT}/${PREFIX}/sbin/ybin +- install -m 0755 ybin/yabootconfig ${ROOT}/${PREFIX}/sbin/yabootconfig +- rm -f ${ROOT}/${PREFIX}/sbin/mkofboot +- ln -s ybin ${ROOT}/${PREFIX}/sbin/mkofboot ++ install -m 0755 ybin/ofpath ${ROOT}/${SBINDIR}/ofpath ++ install -m 0755 ybin/ybin ${ROOT}/${SBINDIR}/ybin ++ install -m 0755 ybin/yabootconfig ${ROOT}/${SBINDIR}/yabootconfig ++ rm -f ${ROOT}/${SBINDIR}/mkofboot ++ ln -s ybin ${ROOT}/${SBINDIR}/mkofboot + @gzip -9 man/*.[58] + install -m 0644 man/bootstrap.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/bootstrap.8.gz + install -m 0644 man/mkofboot.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/mkofboot.8.gz +@@ -216,10 +217,10 @@ + @echo + + deinstall: +- rm -f ${ROOT}/${PREFIX}/sbin/ofpath +- rm -f ${ROOT}/${PREFIX}/sbin/ybin +- rm -f ${ROOT}/${PREFIX}/sbin/yabootconfig +- rm -f ${ROOT}/${PREFIX}/sbin/mkofboot ++ rm -f ${ROOT}/${SBINDIR}/ofpath ++ rm -f ${ROOT}/${SBINDIR}/ybin ++ rm -f ${ROOT}/${SBINDIR}/yabootconfig ++ rm -f ${ROOT}/${SBINDIR}/mkofboot + rm -f ${ROOT}/${PREFIX}/lib/yaboot/yaboot + rm -f ${ROOT}/${PREFIX}/lib/yaboot/ofboot + rm -f ${ROOT}/${PREFIX}/lib/yaboot/addnote diff --git a/yaboot-1.3.13-allow-deep-mntpoint.patch b/yaboot-1.3.13-allow-deep-mntpoint.patch new file mode 100644 index 0000000..3080662 --- /dev/null +++ b/yaboot-1.3.13-allow-deep-mntpoint.patch @@ -0,0 +1,32 @@ +--- yaboot-1.3.13/ybin/ybin~ 2005-08-10 15:09:32.000000000 +0100 ++++ yaboot-1.3.13/ybin/ybin 2005-08-11 16:13:36.000000000 +0100 +@@ -353,17 +353,19 @@ checkconf() + fi + + ## make sure $mntpoint is on $boot, this matters to nvram updating. +- if [ "$(v=`df "$mntpoint" 2> /dev/null | grep ^/dev/` ; echo ${v%%[ ]*})" != "$boot" -a -d "$mntpoint" ] ; then +- echo 1>&2 "$PRG: $mntpoint is not located on $boot" +- local CONFERR=1 +- ## more then one subdirectory deep is not supported. no sed available on boot floppies ( / -> \ ) +- elif [ "$mntpoint" != "$(v=`df "$mntpoint" 2> /dev/null | grep ^/dev/` ; echo ${v##*[ ]})" ] ; then +- echo "$(v=`df "$mntpoint" 2>/dev/null | grep ^/dev/`; m=${v##*[ ]}; echo "${mntpoint##*$m/}")" | grep -q / +- if [ $? = 0 ] ; then +- echo 1>&2 "$PRG:$ERR $mntpoint is more then one subdirectory deep from root of $boot" ++ if [ -n "$magicboot" -o "$nonvram" = 0 ]; then ++ if [ "$(v=`df "$mntpoint" 2> /dev/null | grep ^/dev/` ; echo ${v%%[ ]*})" != "$boot" -a -d "$mntpoint" ] ; then ++ echo 1>&2 "$PRG: $mntpoint is not located on $boot" + local CONFERR=1 +- else +- OFDIR="$(v=`df "$mntpoint" 2>/dev/null | grep ^/dev/`; m=${v##*[ ]}; echo "${mntpoint##*$m/}")" ++ ## more than one subdirectory deep is not supported. no sed available on boot floppies ( / -> \ ) ++ elif [ "$mntpoint" != "$(v=`df "$mntpoint" 2> /dev/null | grep ^/dev/` ; echo ${v##*[ ]})" ] ; then ++ echo "$(v=`df "$mntpoint" 2>/dev/null | grep ^/dev/`; m=${v##*[ ]}; echo "${mntpoint##*$m/}")" | grep -q / ++ if [ $? = 0 ] ; then ++ echo 1>&2 "$PRG:$ERR $mntpoint is more then one subdirectory deep from root of $boot" ++ local CONFERR=1 ++ else ++ OFDIR="$(v=`df "$mntpoint" 2>/dev/null | grep ^/dev/`; m=${v##*[ ]}; echo "${mntpoint##*$m/}")" ++ fi + fi + fi + diff --git a/yaboot-1.3.13-dontwritehome.patch b/yaboot-1.3.13-dontwritehome.patch new file mode 100644 index 0000000..5005418 --- /dev/null +++ b/yaboot-1.3.13-dontwritehome.patch @@ -0,0 +1,13 @@ +--- yaboot-1.3.13/ybin/ybin.dontwritehome 2006-08-10 14:33:06.000000000 -0400 ++++ yaboot-1.3.13/ybin/ybin 2006-08-10 14:33:15.000000000 -0400 +@@ -821,6 +821,10 @@ + return 1 + fi + ++ ## N.B.: SELinux does not like bootloader executables writing to ++ ## root's homedir, so we lie about HOME here. ++ export HOME=/boot ++ + ## hmount is really more of a way to make sure we have a valid HFS + ## filesystem before proceding, and hcopy requires it... + hmount "$boot" > /dev/null diff --git a/yaboot-1.3.13-pegasos-claim.patch b/yaboot-1.3.13-pegasos-claim.patch new file mode 100644 index 0000000..eff5571 --- /dev/null +++ b/yaboot-1.3.13-pegasos-claim.patch @@ -0,0 +1,15 @@ +--- yaboot-1.3.13/second/prom.c~ 2003-11-04 09:13:17.000000000 +0000 ++++ yaboot-1.3.13/second/prom.c 2005-07-29 13:19:35.000000000 +0100 +@@ -547,7 +547,11 @@ prom_sleep (int seconds) + void * + prom_claim (void *virt, unsigned int size, unsigned int align) + { +- return call_prom ("claim", 3, 1, virt, size, align); ++ void *ret = call_prom ("claim", 3, 1, virt, size, align); ++ /* Pegasos II SmartFirmware returns zero for failure, usefully */ ++ if (virt && !ret) ++ ret = (void *)-1; ++ return ret; + } + + void diff --git a/yaboot-1.3.13-pegasos-ext2.patch b/yaboot-1.3.13-pegasos-ext2.patch new file mode 100644 index 0000000..2792f21 --- /dev/null +++ b/yaboot-1.3.13-pegasos-ext2.patch @@ -0,0 +1,82 @@ +--- yaboot-1.3.13/ybin/ybin.ext2 2005-07-29 13:22:40.000000000 +0100 ++++ yaboot-1.3.13/ybin/ybin 2005-07-29 13:23:01.000000000 +0100 +@@ -75,6 +75,8 @@ fi + usemount=no + if (cat /proc/cpuinfo 2> /dev/null | grep ^machine | grep -q 'CHRP IBM') ; then + fstype=raw ++elif (cat /proc/cpuinfo 2> /dev/null | grep ^machine | grep -q 'Pegasos') ; then ++ fstype=ext2 + else + fstype=hfs + fi +@@ -277,13 +279,13 @@ checkconf() + fi + + case "$fstype" in +- hfs|msdos|raw) ++ hfs|msdos|raw|ext2) + ;; + *) + if [ "$ARGFS" = 1 ] ; then +- echo 1>&2 "$PRG: --filesystem must be either \`hfs', \`msdos', or \`raw'" ++ echo 1>&2 "$PRG: --filesystem must be either \`hfs', \`msdos', \`ext2' or \`raw'" + else +- echo 1>&2 "$PRG:$ERR \`fstype' must be either \`hfs', \`msdos', or \`raw'" ++ echo 1>&2 "$PRG:$ERR \`fstype' must be either \`hfs', \`msdos', \`ext2' or \`raw'" + fi + local CONFERR=1 + ;; +@@ -942,12 +944,16 @@ util_install() + ## used by mnt_install so mntpoint= can be supported in a cleaner way. + mnt() + { ++ local mountopts="rw" ++ + ## we can even create bootstrap filesystem images directly if you + ## ever wanted too. + if [ -f "$boot" ] ; then +- local loop=",loop" ++ mountopts="$mountopts,loop" ++ fi ++ if [ "$fstype" = "msdos" ] ; then ++ mountopts="$mountopts,umask=077" + fi +- + if [ -e "$TMP/bootstrap.$$" ] ; then + echo 1>&2 "$PRG: $TMP/bootstrap.$$ exists, aborting." + return 1 +@@ -966,7 +972,7 @@ mnt() + fi + + [ "$VERBOSE" = 1 ] && echo "$PRG: Mounting $boot..." +- mount -t "$fstype" -o rw,umask=077$loop "$boot" "$TMP/bootstrap.$$" ++ mount -t "$fstype" -o rw,$mountopts$loop "$boot" "$TMP/bootstrap.$$" + if [ $? != 0 ] ; then + echo 1>&2 "$PRG: An error occured mounting $boot" + return 1 +@@ -1252,6 +1258,25 @@ mkoffs() + fi + return 0 + ;; ++ ext2) ++ if (command -v mkfs.ext2 > /dev/null 2>&1) ; then ++ [ -x `command -v mkfs.ext2` ] || FAIL=1 ; else FAIL=1 ; fi ++ if [ "$FAIL" = 1 ] ; then ++ echo 1>&2 "$PRG: mkfs.ext2 is not installed or cannot be found" ++ return 1 ++ fi ++ ++ [ "$VERBOSE" = 1 ] && echo "$PRG: Creating ext2 filesystem on $boot..." ++ if (command -v dd > /dev/null 2>&1) ; then ++ dd if=/dev/zero of="$boot" bs=512 count=1600 > /dev/null 2>&1 ++ fi ++ mkfs.ext2 -L bootstrap "$boot" > /dev/null ++ if [ $? != 0 ] ; then ++ echo 1>&2 "$PRG: ext2 filesystem creation failed!" ++ return 1 ++ fi ++ return 0 ++ ;; + esac + } + diff --git a/yaboot-1.3.13-pegasos-serial.patch b/yaboot-1.3.13-pegasos-serial.patch new file mode 100644 index 0000000..8341e12 --- /dev/null +++ b/yaboot-1.3.13-pegasos-serial.patch @@ -0,0 +1,14 @@ +--- yaboot-1.3.13/second/prom.c~ 2005-08-10 14:53:10.000000000 +0100 ++++ yaboot-1.3.13/second/prom.c 2005-08-10 15:07:16.000000000 +0100 +@@ -368,10 +368,8 @@ prom_getchar () + char c[4]; + int a; + +- while ((a = (int)call_prom ("read", 3, 1, prom_stdin, c, 4)) == 0) ++ while ((a = (int)call_prom ("read", 3, 1, prom_stdin, c, 4)) <= 0) + ; +- if (a == -1) +- prom_abort ("EOF on console\n"); + if (a == 3 && c[0] == '\e' && c[1] == '[') + return 0x100 | c[2]; + return c[0]; diff --git a/yaboot-1.3.13-yabootconfig.patch b/yaboot-1.3.13-yabootconfig.patch new file mode 100644 index 0000000..7360cd1 --- /dev/null +++ b/yaboot-1.3.13-yabootconfig.patch @@ -0,0 +1,249 @@ +--- yaboot-1.3.13/ybin/yabootconfig.yabootconfig 2005-07-25 16:09:39.000000000 -0400 ++++ yaboot-1.3.13/ybin/yabootconfig 2005-07-25 16:25:03.000000000 -0400 +@@ -34,6 +34,7 @@ + NOINSTALL=0 + QUIET=0 + DEBUG=0 ++LABEL="Linux" + SIGINT="$PRG: Interrupt caught ... exiting" + export LC_COLLATE=C + +@@ -319,6 +320,16 @@ + exit 1 + fi + ;; ++ --kernel) ++ if [ -n "$2" ] ; then ++ KERNELIMAGE="$2" ++ shift 2 ++ else ++ echo 1>&2 "$PRG: option requires an argument $1" ++ echo 1>&2 "Try \`$PRG --help' for more information." ++ exit 1 ++ fi ++ ;; + --kernel-args) + if [ -n "$2" ] ; then + KERNARGS="$2" +@@ -347,10 +358,88 @@ + NOINSTALL=1 + shift 1 + ;; ++ --enablecdboot) ++ CDBOOT=1 ++ shift 1 ++ ;; ++ --enablenetboot) ++ NETBOOT=1 ++ shift 1 ++ ;; + --debug) + DEBUG=1 + shift 1 + ;; ++ --delay) ++ if [ -n "$2" ] ; then ++ DELAY=$2 ++ shift 2 ++ else ++ echo 1>&2 "$PRG: option requires an argument $1" ++ echo 1>&2 "Try \`$PRG --help' for more information." ++ exit 1 ++ fi ++ ;; ++ --label) ++ if [ -n "$2" ] ; then ++ LABEL=$2 ++ shift 2 ++ else ++ echo 1>&2 "$PRG: option requires an argument $1" ++ echo 1>&2 "Try \`$PRG --help' for more information." ++ exit 1 ++ fi ++ ;; ++ --initrd) ++ if [ -n "$2" ] ; then ++ INITRDPATH=$2 ++ shift 2 ++ else ++ echo 1>&2 "$PRG: option requires an argument $1" ++ echo 1>&2 "Try \`$PRG --help' for more information." ++ exit 1 ++ fi ++ ;; ++ --macosx) ++ if [ -n "$2" ] ; then ++ MACOSXDEV=$2 ++ shift 2 ++ else ++ echo 1>&2 "$PRG: option requires an argument $1" ++ echo 1>&2 "Try \`$PRG --help' for more information." ++ exit 1 ++ fi ++ ;; ++ --macos) ++ if [ -n "$2" ] ; then ++ MACOSDEV=$2 ++ shift 2 ++ else ++ echo 1>&2 "$PRG: option requires an argument $1" ++ echo 1>&2 "Try \`$PRG --help' for more information." ++ exit 1 ++ fi ++ ;; ++ --darwin) ++ if [ -n "$2" ] ; then ++ DARWINDEV=$2 ++ shift 2 ++ else ++ echo 1>&2 "$PRG: option requires an argument $1" ++ echo 1>&2 "Try \`$PRG --help' for more information." ++ exit 1 ++ fi ++ ;; ++ --defaultos) ++ if [ -n "$2" ] ; then ++ DEFOS=$2 ++ shift 2 ++ else ++ echo 1>&2 "$PRG: option requires an argument $1" ++ echo 1>&2 "Try \`$PRG --help' for more information." ++ exit 1 ++ fi ++ ;; + "") + break + ;; +@@ -474,7 +563,7 @@ + READLINKKV=`readlink /usr/src/linux` + ## find the kernel in the usual places and (if not --quiet) ask the + ## user if we cannot find one. +-for k in "vmlinux" "vmlinux-`uname -r`" "vmlinux-`uname -r`" "$READLINKKV" ; do ++for k in "${KERNELIMAGE}" "vmlinux" "vmlinux-`uname -r`" "vmlinux-`uname -r`" "$READLINKKV" ; do + if [ -f "${CHROOT}${k}" ] ; then + KERNEL="${CHROOT}${k}" + break; +@@ -721,6 +812,36 @@ + HEADER="## see also: /usr/share/doc/yaboot/examples for example configurations.\n" + fi + ++## find the kernel in the usual places and (if not --quiet) ask the ++## user if we cannot find one. ++if [ -f "${CHROOT}${INITRDPATH}" ] ; then ++ REALINITRD="${CHROOT}${INITRDPATH}" ++ ++ ## if there is a separate /boot partition we must strip off the /boot ++ ## mountpoint or else yaboot will not find the kernel. ++ if [ "$KERNDIR" != "$CHROOT" ] ; then ++ INITRD="${REALINITRD##*$KERNDIR}" ++ else ++ INITRD="$REALINITRD" ++ fi ++ ++ ## fix chrooted path ++ if [ "$CHROOT" != / ] ; then ++ INITRD="${INITRD##*$CHROOT}" ++ fi ++ ++ ## fix relative path (caused by chroot path fix) ++ case "$INITRD" in ++ /*) ++ true ++ ;; ++ *) ++ INITRD="/${INITRD}" ++ ;; ++ esac ++ INITRDLINE="\tinitrd=$INITRD\n" ++fi ++ + ## setup append line + if [ -n "$KERNARGS" ] ; then + APPEND="\tappend=\"${KERNARGS}\"\n" +@@ -731,24 +850,64 @@ + INITRDIMGS="\tinitrd=$INITRDIMG\n\tinitrd-size=8192\n" + fi + ++## setup default OS bits for ybin ++if [ -n "$DEFOS" ] ; then ++ if [ "$DEFOS" = "macosx" ] ; then ++ DEFAULTOS="defaultos=${DEFOS}\n" ++ elif [ "$DEFOS" = "macos" ] ; then ++ DEFAULTOS="defaultos=${DEFOS}\n" ++ elif [ "$DEFOS" = "darwin" ] ; then ++ DEFAULTOS="defaultos=${DEFOS}\n" ++ else ++ DEFAULTOS="defaultos=linux\n" ++ fi ++else ++ DEFAULTOS="defaultos=linux\n" ++fi ++if [ -n "$DELAY" ] ; then ++ MENUDELAY="delay=${DELAY}\n" ++fi ++ ++## setup enabling cd or network boot from OF ++if [ -n "$CDBOOT" ] ; then ++ ENABLECDBOOT="enablecdboot\n" ++fi ++if [ -n "$NETBOOT" ] ; then ++ ENABLENETBOOT="enablenetboot\n" ++fi ++ ++MESG='"Welcome to Red Hat Linux!\\nHit for boot options.\\n\\n"' ++ + ## generate global section of yaboot.conf +-GLOBAL="## yaboot.conf generated by $PRG $VERSION +-## +-## run: \"man yaboot.conf\" for details. Do not make changes until you have!! +-${HEADER}## +-## For a dual-boot menu, add one or more of: +-## bsd=/dev/hdaX, macos=/dev/hdaY, macosx=/dev/hdaZ\n +-boot=${BOOT}${DEVICE:-} ++GLOBAL="boot=${BOOT}${DEVICE:-} ++init-message=$MESG + partition=$PARTITION +-root=$ROOT + timeout=30 +-install=${INSTALL}${OFBOOT:-}\n" ++install=${INSTALL}${OFBOOT:-} ++default=$LABEL ++${DEFAULTOS:-}${MENUDELAY:-}${ENABLECDBOOT:-}${ENABLENETBOOT:-}" + + ## generate image= section + IMAGES=" + image=$IMAGE +-\tlabel=Linux +-\tread-only\n${APPEND:-}${INITRDIMGS:-}" ++\tlabel=$LABEL ++\troot=$ROOT ++\tread-only\n ++${INITRDLINE-}${APPEND:-}" ++ ++if [ -n "$MACOSXDEV" ] ; then ++ MACOSX="macosx=${MACOSXDEV}\n" ++fi ++ ++if [ -n "$MACOSDEV" ] ; then ++ MACOS="macos=${MACOSDEV}\n" ++fi ++ ++if [ -n "$DARWINDEV" ] ; then ++ DARWIN="darwin=${DARWINDEV}\n" ++fi ++ ++OTHER="${MACOSX}${MACOS}${DARWIN}${BSD}" + + ## safely create a tmp file then move it into place after we are sure + ## it was written. +@@ -767,7 +928,9 @@ + exit 1 + fi + +-$PRINTF "${GLOBAL}${IMAGES}" > "$TMPCONF" ++printf "${GLOBAL} ++${IMAGES} ++${OTHER}" > "$TMPCONF" + if [ $? != 0 ] ; then + echo 1>&2 "$PRG: Unable to write temporary file ${TMPCONF}, aborting..." + exit 1 diff --git a/yaboot-1.3.14-256-RMA.patch b/yaboot-1.3.14-256-RMA.patch new file mode 100644 index 0000000..285c10a --- /dev/null +++ b/yaboot-1.3.14-256-RMA.patch @@ -0,0 +1,99 @@ +Index: yaboot-1.3.14-30/include/prom.h +=================================================================== +--- yaboot-1.3.14-30.orig/include/prom.h 2010-05-25 14:37:24.309622517 +1000 ++++ yaboot-1.3.14-30/include/prom.h 2010-05-25 14:37:27.803373148 +1000 +@@ -158,5 +158,6 @@ + struct bootp_packet * prom_get_netinfo (void); + char * prom_get_mac (struct bootp_packet * packet); + char * prom_get_ip (struct bootp_packet * packet); ++void *prom_rma_size(void); + + #endif +Index: yaboot-1.3.14-30/second/prom.c +=================================================================== +--- yaboot-1.3.14-30.orig/second/prom.c 2010-05-25 14:37:24.309622517 +1000 ++++ yaboot-1.3.14-30/second/prom.c 2010-05-25 14:37:27.805375106 +1000 +@@ -536,7 +536,16 @@ + prom_claim_chunk(void *virt, unsigned int size, unsigned int align) + { + void *found, *addr; +- for(addr=virt; addr <= (void*)PROM_CLAIM_MAX_ADDR; ++ static void *claim_max_addr = -1; ++ ++ if (claim_max_addr == (void*)-1) { ++ claim_max_addr = prom_rma_size(); ++ if (claim_max_addr < PROM_CLAIM_MAX_ADDR) ++ claim_max_addr = PROM_CLAIM_MAX_ADDR; ++ DEBUG_F("Setting claim_max_addr to 0x%x\n", (int)claim_max_addr); ++ } ++ ++ for(addr=virt; addr <= (void*)claim_max_addr; + addr+=(0x100000/sizeof(addr))) { + found = prom_claim(addr, size, 0); + if (found != (void *)-1) { +@@ -739,6 +748,32 @@ + return conf_path; + } + ++void *prom_rma_size(void) ++{ ++ int rc; ++ ihandle n; ++ u64 *start, *end; ++ unsigned char buf[16]; /* This will store 2 64-bit values */ ++ ++ DEBUG_ENTER; ++ ++ n = prom_finddevice("/memory@0"); ++ DEBUG_F("n = %x\n", (int)n); ++ rc = prom_getprop(n, "reg", &buf, 16); ++ DEBUG_F("rc = %d\n", rc); ++ ++ /* If the getprop() failed fill the buffer with some known value */ ++ if (rc == -1) ++ memset(&buf[0], 0xff, 16); ++ ++ start = (u64*)&buf[0]; ++ end = (u64*)&buf[8]; ++ DEBUG_F("start=0x%Lx, end=0x%Lx\n", *start, *end); ++ ++ DEBUG_LEAVE(0); ++ return (void*)*end; ++} ++ + /* + * Local variables: + * c-file-style: "k&r" +Index: yaboot-1.3.14-30/second/yaboot.c +=================================================================== +--- yaboot-1.3.14-30.orig/second/yaboot.c 2010-05-25 14:37:20.729370528 +1000 ++++ yaboot-1.3.14-30/second/yaboot.c 2010-05-25 14:37:27.810374623 +1000 +@@ -121,6 +121,7 @@ + struct boot_fspec_t boot; + int _machine = _MACH_Pmac; + int flat_vmlinux; ++u64 rma_size = 0; + + #ifdef CONFIG_COLOR_TEXT + +@@ -239,6 +240,9 @@ + } + } + ++ rma_size = (u64)prom_rma_size(); ++ prom_printf("System has %Ld Mbytes in RMA\n", rma_size >> 20); ++ + DEBUG_F("Running on _machine = %d\n", _machine); + DEBUG_SLEEP; + +@@ -1258,8 +1262,8 @@ + (unsigned long)(initrd_size)); + + /* Check to see if we're near the top of the RMA */ +- /* Cheat and assume the RMA == 128Mb */ +- if (initrd_end > 0x7000000) { ++ /* Cheat and assume RTAS will be ~16Mb */ ++ if (initrd_end > rma_size - 0x1000000) { + unsigned long new_initrd_end, free_len; + unsigned long initrd_claim_len = initrd_end - (unsigned long)initrd_base; + diff --git a/yaboot-1.3.14-better_netboot.patch b/yaboot-1.3.14-better_netboot.patch new file mode 100644 index 0000000..0ed9afd --- /dev/null +++ b/yaboot-1.3.14-better_netboot.patch @@ -0,0 +1,715 @@ +diff -pur yaboot-1.3.14.orig/include/debug.h yaboot-1.3.14/include/debug.h +--- yaboot-1.3.14.orig/include/debug.h 2007-08-18 00:29:26.000000000 +1000 ++++ yaboot-1.3.14/include/debug.h 2010-02-08 13:07:31.954223039 +1100 +@@ -32,8 +32,8 @@ + prom_printf( fmt, ## args );\ + } + # define DEBUG_OPEN DEBUG_F( "dev=%s, part=0x%p (%d), file_name=%s\n",\ +- dev_name, part, part ? part->part_number : -1,\ +- file_name) ++ fspec->dev, part, part ? part->part_number : -1,\ ++ fspec->file) + # define DEBUG_SLEEP prom_sleep(3) + #else + #define DEBUG_ENTER +diff -pur yaboot-1.3.14.orig/include/file.h yaboot-1.3.14/include/file.h +--- yaboot-1.3.14.orig/include/file.h 2007-08-18 00:29:26.000000000 +1000 ++++ yaboot-1.3.14/include/file.h 2010-02-08 13:07:31.955220185 +1100 +@@ -39,7 +39,13 @@ struct boot_file_t; + struct boot_fspec_t { + char* dev; /* OF device path */ + int part; /* Partition number or -1 */ ++ char* siaddr; /* Server address */ + char* file; /* File path */ ++ char* ciaddr; /* Client address */ ++ char* giaddr; /* Gateway address */ ++ char* bootp_retries; /* Bootp retries */ ++ char* tftp_retries; /* TFTP retries */ ++ char* addl_params; /* copy all additional parameters */ + }; + + struct boot_file_t { +@@ -63,7 +69,7 @@ struct boot_file_t { + }; + + extern int +-open_file(const struct boot_fspec_t* spec, ++open_file(struct boot_fspec_t* spec, + struct boot_file_t* file); + + extern int +diff -pur yaboot-1.3.14.orig/include/fs.h yaboot-1.3.14/include/fs.h +--- yaboot-1.3.14.orig/include/fs.h 2007-08-18 00:29:26.000000000 +1000 ++++ yaboot-1.3.14/include/fs.h 2010-02-08 13:07:31.958474719 +1100 +@@ -27,14 +27,14 @@ + #include "file.h" + + int fserrorno; ++struct boot_fspec_t; + + struct fs_t { + const char* name; + + int (*open)( struct boot_file_t* file, +- const char* dev_name, + struct partition_t* part, +- const char* file_name); ++ struct boot_fspec_t* fspec); + + int (*read)( struct boot_file_t* file, + unsigned int size, +@@ -49,7 +49,7 @@ struct fs_t { + extern const struct fs_t *fs_of; + extern const struct fs_t *fs_of_netboot; + +-const struct fs_t *fs_open(struct boot_file_t *file, const char *dev_name, +- struct partition_t *part, const char *file_name); ++const struct fs_t *fs_open(struct boot_file_t *file, ++ struct partition_t *part, struct boot_fspec_t *fspec); + + #endif +diff -pur yaboot-1.3.14.orig/second/file.c yaboot-1.3.14/second/file.c +--- yaboot-1.3.14.orig/second/file.c 2007-08-18 00:29:26.000000000 +1000 ++++ yaboot-1.3.14/second/file.c 2010-02-08 13:07:31.960189430 +1100 +@@ -38,19 +38,56 @@ + + extern char bootdevice[]; + +-static char *netdev_path_to_filename(const char *path) ++/* Convert __u32 into std, dotted quad string, leaks like a sive :( */ ++static char * ++ipv4_to_str(__u32 ip) + { +- char *tmp, *args, *filename; +- size_t len; ++ char *buf = malloc(sizeof("000.000.000.000")); + +- DEBUG_F("path = %s\n", path); ++ sprintf(buf,"%u.%u.%u.%u", ++ (ip & 0xff000000) >> 24, (ip & 0x00ff0000) >> 16, ++ (ip & 0x0000ff00) >> 8, (ip & 0x000000ff)); + +- if (!path) ++ return buf; ++} ++ ++/* ++ * Copy the string from source to dest till newline or comma(,) is seen ++ * in the source. ++ * Move source and dest pointers respectively. ++ * Returns pointer to the start of the string that has just been copied. ++ */ ++static char * ++scopy(char **dest, char **source) ++{ ++ char *ret = *dest; ++ ++ if (!**source) + return NULL; + +- args = strrchr(path, ':'); ++ while (**source != ',' && **source != '\0') ++ *(*dest)++ = *(*source)++; ++ if (**source != '\0') ++ *(*source)++; ++ **dest = '\0'; ++ *(*dest)++; ++ return ret; ++} ++ ++/* ++ * Extract all the ipv4 arguments from the bootpath provided and fill result ++ * Returns 1 on success, 0 on failure. ++ */ ++static int ++extract_ipv4_args(char *imagepath, struct boot_fspec_t *result) ++{ ++ char *tmp, *args, *str, *start; ++ ++ args = strrchr(imagepath, ':'); + if (!args) +- return NULL; ++ return 1; ++ ++ start = args; /* used to see if we read any optional parameters */ + + /* The obp-tftp device arguments should be at the end of + * the argument list. Skip over any extra arguments (promiscuous, +@@ -77,46 +114,110 @@ static char *netdev_path_to_filename(con + if (tmp && tmp > args) + args = tmp + strlen("rarp"); + +- args = strchr(args, ','); ++ if (args != start) /* we read some parameters, so go past the next comma(,) */ ++ args = strchr(args, ','); + if (!args) +- return NULL; ++ return 1; ++ ++ str = malloc(strlen(args) + 1); /*long enough to hold all strings */ ++ if (!str) ++ return 0; ++ ++ if (args[-1] != ':') ++ args++; /* If comma(,) is not immediately followed by ':' then go past the , */ + +- tmp = args; +- tmp--; +- /* If the preceding character is ':' then there were no +- * non-obp-tftp arguments and we know we're right up to the +- * filename. Otherwise, we must advance args once more. ++ /* ++ * read the arguments in order: siaddr,filename,ciaddr,giaddr, ++ * bootp-retries,tftp-retries,addl_prameters + */ +- args++; +- if (*tmp != ':') { +- args = strchr(args, ','); +- if (!args) +- return NULL; +- args++; ++ result->siaddr = scopy(&str, &args); ++ result->file = scopy(&str, &args); ++ result->ciaddr = scopy(&str, &args); ++ result->giaddr = scopy(&str, &args); ++ result->bootp_retries = scopy(&str, &args); ++ result->tftp_retries = scopy(&str, &args); ++ if (*args) { ++ result->addl_params = strdup(args); ++ if (!result->addl_params) ++ return 0; + } ++ return 1; ++} + +- /* filename may be empty; e.g. enet:192.168.1.1,,192.168.1.2 */ +- if (*args == ',') { +- DEBUG_F("null filename\n"); +- return NULL; ++/* ++ * Check netinfo for ipv4 parameters and add them to the fspec iff the ++ * fspec has no existing value. ++ * ++ * Returns 1 on success, 0 on failure. ++ */ ++static int ++extract_netinfo_args(struct boot_fspec_t *result) ++{ ++ struct bootp_packet *packet; ++ ++ /* Check to see if we can get the [scyg]iaddr fields from netinfo */ ++ packet = prom_get_netinfo(); ++ if (packet == NULL) ++ return 0; ++ ++ DEBUG_F("We have a boot packet\n"); ++ DEBUG_F(" siaddr = <%x>\n", packet->siaddr); ++ DEBUG_F(" ciaddr = <%x>\n", packet->ciaddr); ++ DEBUG_F(" yiaddr = <%x>\n", packet->yiaddr); ++ DEBUG_F(" giaddr = <%x>\n", packet->giaddr); ++ ++ /* Try to fallback to yiaddr if ciaddr is empty. Broken? */ ++ if (packet->ciaddr == 0 && packet->yiaddr != 0) ++ packet->ciaddr = packet->yiaddr; ++ ++ if ((result->siaddr == NULL || *(result->siaddr) == NULL) ++ && packet->siaddr != 0) ++ result->siaddr = ipv4_to_str(packet->siaddr); ++ if ((result->ciaddr == NULL || *(result->ciaddr) == NULL) ++ && packet->ciaddr != 0) ++ result->ciaddr = ipv4_to_str(packet->ciaddr); ++ if ((result->giaddr == NULL || *(result->giaddr) == NULL) ++ && packet->giaddr != 0) ++ result->giaddr = ipv4_to_str(packet->giaddr); ++ ++ /* FIXME: Yck! if we /still/ do not have a gateway then "cheat" and use ++ * the server. This will be okay if the client and server are on ++ * the same IP network, if not then lets hope the server does ICMP ++ * redirections */ ++ if (result->giaddr == NULL) { ++ result->giaddr = ipv4_to_str(packet->siaddr); ++ DEBUG_F("Forcing giaddr to siaddr <%s>\n", result->giaddr); + } + +- /* Now see whether there are more args following the filename. */ +- tmp = strchr(args, ','); +- if (!tmp) +- len = strlen(args) + 1; +- else +- len = tmp - args + 1; ++ return 1; ++} + +- filename = malloc(len); +- if (!filename) +- return NULL; ++/* ++ * Extract all the arguments provided in the imagepath and fill it in result. ++ * Returns 1 on success, 0 on failure. ++ */ ++static int ++extract_netboot_args(char *imagepath, struct boot_fspec_t *result) ++{ ++ int ret; ++ ++ DEBUG_F("imagepath = %s\n", imagepath); + +- strncpy(filename, args, len); +- filename[len - 1] = '\0'; ++ if (!imagepath) ++ return 1; + +- DEBUG_F("filename = %s\n", filename); +- return filename; ++ ret = extract_ipv4_args(imagepath, result); ++ ret |= extract_netinfo_args(result); ++ ++ DEBUG_F("siaddr = <%s>\n", result->siaddr); ++ DEBUG_F("file = <%s>\n", result->file); ++ DEBUG_F("ciaddr = <%s>\n", result->ciaddr); ++ DEBUG_F("giaddr = <%s>\n", result->giaddr); ++ DEBUG_F("bootp_retries = <%s>\n", result->bootp_retries); ++ DEBUG_F("tftp_retries = <%s>\n", result->tftp_retries); ++ DEBUG_F("addl_params = <%s>\n", result->addl_params); ++ ++ return ret; + } + + static char *netdev_path_to_dev(const char *path) +@@ -163,6 +264,10 @@ static char *netdev_path_to_dev(const ch + - enet:,/tftpboot/vmlinux + - enet:bootp + - enet:0 ++ - arguments for obp-tftp open as specified in section 4.1 of ++ http://playground.sun.com/1275/practice/obp-tftp/tftp1_0.pdf ++ [bootp,]siaddr,filename,ciaddr,giaddr,bootp-retries,tftp-retries ++ ex: enet:bootp,10.0.0.11,bootme,10.0.0.12,10.0.0.1,5,5 + Supported only if defdevice == NULL + - disc + - any other device path lacking a : +@@ -179,6 +284,9 @@ parse_device_path(char *imagepath, char + char *defdev = NULL; + int device_kind = -1; + ++ DEBUG_F("imagepath = %s; defdevice %s; defpart %d, deffile %s\n", ++ imagepath, defdevice, defpart, deffile); ++ + result->dev = NULL; + result->part = -1; + result->file = NULL; +@@ -247,10 +355,15 @@ parse_device_path(char *imagepath, char + } + + if (device_kind == FILE_DEVICE_NET) { +- if (strchr(ipath, ':')) +- result->file = netdev_path_to_filename(ipath); +- else ++ if (strchr(ipath, ':')) { ++ if (extract_netboot_args(ipath, result) == 0) ++ return 0; ++ } else { ++ /* If we didn't get a ':' then look only in netinfo */ ++ if (extract_netinfo_args(result) == 0) ++ return 0; + result->file = strdup(ipath); ++ } + + if (!defdev) + result->dev = netdev_path_to_dev(ipath); +@@ -287,15 +400,14 @@ parse_device_path(char *imagepath, char + + static int + file_block_open( struct boot_file_t* file, +- const char* dev_name, +- const char* file_name, ++ struct boot_fspec_t* fspec, + int partition) + { + struct partition_t* parts; + struct partition_t* p; + struct partition_t* found; + +- parts = partitions_lookup(dev_name); ++ parts = partitions_lookup(fspec->dev); + found = NULL; + + #if DEBUG +@@ -308,7 +420,7 @@ file_block_open( struct boot_file_t* fil + DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx\n", + p->part_number, p->part_start, p->part_size ); + if (partition == -1) { +- file->fs = fs_open( file, dev_name, p, file_name ); ++ file->fs = fs_open( file, p, fspec ); + if (file->fs == NULL || fserrorno != FILE_ERR_OK) + continue; + else { +@@ -328,7 +440,7 @@ file_block_open( struct boot_file_t* fil + * cases, let OF figure out a default partition. + */ + DEBUG_F( "Using OF defaults.. (found = %p)\n", found ); +- file->fs = fs_open( file, dev_name, found, file_name ); ++ file->fs = fs_open( file, found, fspec ); + + done: + if (parts) +@@ -338,12 +450,10 @@ done: + } + + static int +-file_net_open( struct boot_file_t* file, +- const char* dev_name, +- const char* file_name) ++file_net_open(struct boot_file_t* file, struct boot_fspec_t *fspec) + { + file->fs = fs_of_netboot; +- return fs_of_netboot->open(file, dev_name, NULL, file_name); ++ return fs_of_netboot->open(file, NULL, fspec); + } + + static int +@@ -380,7 +490,7 @@ static struct fs_t fs_default = + }; + + +-int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file) ++int open_file(struct boot_fspec_t* spec, struct boot_file_t* file) + { + int result; + +@@ -399,10 +509,10 @@ int open_file(const struct boot_fspec_t* + switch(file->device_kind) { + case FILE_DEVICE_BLOCK: + DEBUG_F("device is a block device\n"); +- return file_block_open(file, spec->dev, spec->file, spec->part); ++ return file_block_open(file, spec, spec->part); + case FILE_DEVICE_NET: + DEBUG_F("device is a network device\n"); +- return file_net_open(file, spec->dev, spec->file); ++ return file_net_open(file, spec); + } + return 0; + } +diff -pur yaboot-1.3.14.orig/second/fs.c yaboot-1.3.14/second/fs.c +--- yaboot-1.3.14.orig/second/fs.c 2007-08-18 00:29:26.000000000 +1000 ++++ yaboot-1.3.14/second/fs.c 2010-02-08 13:07:31.963189318 +1100 +@@ -56,12 +56,12 @@ const struct fs_t *fs_of = &of_filesyste + const struct fs_t *fs_of_netboot = &of_net_filesystem; /* needed by file.c */ + + const struct fs_t * +-fs_open(struct boot_file_t *file, const char *dev_name, +- struct partition_t *part, const char *file_name) ++fs_open(struct boot_file_t *file, ++ struct partition_t *part, struct boot_fspec_t *fspec) + { + const struct fs_t **fs; + for (fs = block_filesystems; *fs; fs++) +- if ((fserrorno = (*fs)->open(file, dev_name, part, file_name)) != FILE_ERR_BAD_FSYS) ++ if ((fserrorno = (*fs)->open(file, part, fspec)) != FILE_ERR_BAD_FSYS) + break; + + return *fs; +diff -pur yaboot-1.3.14.orig/second/fs_ext2.c yaboot-1.3.14/second/fs_ext2.c +--- yaboot-1.3.14.orig/second/fs_ext2.c 2010-02-08 13:06:21.083438946 +1100 ++++ yaboot-1.3.14/second/fs_ext2.c 2010-02-08 13:07:31.964188908 +1100 +@@ -46,9 +46,8 @@ typedef int FILE; + #include "ext2fs/ext2fs.h" + + static int ext2_open( struct boot_file_t* file, +- const char* dev_name, + struct partition_t* part, +- const char* file_name); ++ struct boot_fspec_t* fspec); + static int ext2_read( struct boot_file_t* file, + unsigned int size, + void* buffer); +@@ -123,14 +122,15 @@ void com_err (const char *a, long i, con + + static int + ext2_open( struct boot_file_t* file, +- const char* dev_name, + struct partition_t* part, +- const char* file_name) ++ struct boot_fspec_t* fspec) + { + int result = 0; + int error = FILE_ERR_NOTFOUND; + static char buffer[1024]; + int ofopened = 0; ++ char *dev_name = fspec->dev; ++ char *file_name = fspec->file; + + DEBUG_ENTER; + DEBUG_OPEN; +diff -pur yaboot-1.3.14.orig/second/fs_iso.c yaboot-1.3.14/second/fs_iso.c +--- yaboot-1.3.14.orig/second/fs_iso.c 2007-08-18 00:29:26.000000000 +1000 ++++ yaboot-1.3.14/second/fs_iso.c 2010-02-08 13:07:31.965185705 +1100 +@@ -29,9 +29,8 @@ + #include "errors.h" + + static int iso_open( struct boot_file_t* file, +- const char* dev_name, + struct partition_t* part, +- const char* file_name); ++ struct boot_fspec_t* fspec); + static int iso_read( struct boot_file_t* file, + unsigned int size, + void* buffer); +@@ -50,9 +49,8 @@ struct fs_t iso_filesystem = + + static int + iso_open( struct boot_file_t* file, +- const char* dev_name, + struct partition_t* part, +- const char* file_name) ++ struct boot_fspec_t* fspec) + { + return FILE_ERR_BAD_FSYS; + } +diff -pur yaboot-1.3.14.orig/second/fs_of.c yaboot-1.3.14/second/fs_of.c +--- yaboot-1.3.14.orig/second/fs_of.c 2010-02-08 13:06:21.058435316 +1100 ++++ yaboot-1.3.14/second/fs_of.c 2010-02-08 13:08:27.845210705 +1100 +@@ -45,17 +45,17 @@ + #include "debug.h" + + #define LOAD_BUFFER_POS 0x00000000 +-#define LOAD_BUFFER_SIZE 0x01000000 ++#define LOAD_BUFFER_SIZE 0x02000000 + +-static int of_open(struct boot_file_t* file, const char* dev_name, +- struct partition_t* part, const char* file_name); ++static int of_open(struct boot_file_t* file, ++ struct partition_t* part, struct boot_fspec_t* fspec); + static int of_read(struct boot_file_t* file, unsigned int size, void* buffer); + static int of_seek(struct boot_file_t* file, unsigned int newpos); + static int of_close(struct boot_file_t* file); + + +-static int of_net_open(struct boot_file_t* file, const char* dev_name, +- struct partition_t* part, const char* file_name); ++static int of_net_open(struct boot_file_t* file, ++ struct partition_t* part, struct boot_fspec_t* fspec); + static int of_net_read(struct boot_file_t* file, unsigned int size, void* buffer); + static int of_net_seek(struct boot_file_t* file, unsigned int newpos); + +@@ -79,8 +79,8 @@ struct fs_t of_net_filesystem = + }; + + static int +-of_open(struct boot_file_t* file, const char* dev_name, +- struct partition_t* part, const char* file_name) ++of_open(struct boot_file_t* file, ++ struct partition_t* part, struct boot_fspec_t* fspec) + { + static char buffer[1024]; + char *filename; +@@ -89,7 +89,7 @@ of_open(struct boot_file_t* file, const + DEBUG_ENTER; + DEBUG_OPEN; + +- strncpy(buffer, dev_name, 768); ++ strncpy(buffer, fspec->dev, 768); + strcat(buffer, ":"); + if (part) { + if (part->sys_ind == LINUX_RAID) { +@@ -101,10 +101,10 @@ of_open(struct boot_file_t* file, const + sprintf(pn, "%02d", part->part_number); + strcat(buffer, pn); + } +- if (file_name && strlen(file_name)) { ++ if (fspec->file && strlen(fspec->file)) { + if (part) + strcat(buffer, ","); +- filename = strdup(file_name); ++ filename = strdup(fspec->file); + for (p = filename; *p; p++) + if (*p == '/') + *p = '\\'; +@@ -131,25 +131,47 @@ of_open(struct boot_file_t* file, const + } + + static int +-of_net_open(struct boot_file_t* file, const char* dev_name, +- struct partition_t* part, const char* file_name) ++of_net_open(struct boot_file_t* file, ++ struct partition_t* part, struct boot_fspec_t* fspec) + { + static char buffer[1024]; +- char *filename; ++ char *filename = NULL; + char *p; + + DEBUG_ENTER; + DEBUG_OPEN; + +- strncpy(buffer, dev_name, 768); +- if (file_name && strlen(file_name)) { +- strcat(buffer, ","); +- filename = strdup(file_name); ++ if (fspec->file && strlen(fspec->file)) { ++ filename = strdup(fspec->file); + for (p = filename; *p; p++) + if (*p == '/') + *p = '\\'; +- strcat(buffer, filename); +- free(filename); ++ } ++ ++ DEBUG_F("siaddr <%s>; filename <%s>; ciaddr <%s>; giaddr <%s>;\n", ++ fspec->siaddr, filename, fspec->ciaddr, fspec->giaddr); ++ strncpy(buffer, fspec->dev, 768); ++ /* If we didn't get a ':' include one */ ++ if (fspec->dev[strlen(fspec->dev)-1] != ':') ++ strcat(buffer, ":"); ++ strcat(buffer, fspec->siaddr); ++ strcat(buffer, ","); ++ strcat(buffer, filename); ++ strcat(buffer, ","); ++ strcat(buffer, fspec->ciaddr); ++ strcat(buffer, ","); ++ strcat(buffer, fspec->giaddr); ++ ++ /* If /packages/cas exists the we have a "new skool" tftp */ ++ if (prom_finddevice("/packages/cas") != PROM_INVALID_HANDLE) { ++ strcat(buffer, ","); ++ strcat(buffer, fspec->bootp_retries); ++ strcat(buffer, ","); ++ strcat(buffer, fspec->tftp_retries); ++ strcat(buffer, ","); ++ strcat(buffer, fspec->addl_params); ++ } else { ++ DEBUG_F("No \"/packages/cas\" using simple args\n") + } + + DEBUG_F("Opening: \"%s\"\n", buffer); +diff -pur yaboot-1.3.14.orig/second/fs_reiserfs.c yaboot-1.3.14/second/fs_reiserfs.c +--- yaboot-1.3.14.orig/second/fs_reiserfs.c 2010-02-08 13:06:21.058435316 +1100 ++++ yaboot-1.3.14/second/fs_reiserfs.c 2010-02-08 13:07:31.970189661 +1100 +@@ -33,8 +33,8 @@ + #include "reiserfs/reiserfs.h" + + /* Exported in struct fs_t */ +-static int reiserfs_open( struct boot_file_t *file, const char *dev_name, +- struct partition_t *part, const char *file_name ); ++static int reiserfs_open( struct boot_file_t *file, struct partition_t *part, ++ struct boot_fspec_t *fspec); + static int reiserfs_read( struct boot_file_t *file, unsigned int size, + + void *buffer ); +@@ -63,10 +63,12 @@ int errnum; + + + static int +-reiserfs_open( struct boot_file_t *file, const char *dev_name, +- struct partition_t *part, const char *file_name ) ++reiserfs_open( struct boot_file_t *file, struct partition_t *part, ++ struct boot_fspec_t *fspec) + { + static char buffer[1024]; ++ char *dev_name = fspec->dev; ++ char *file_name = fspec->file; + + DEBUG_ENTER; + DEBUG_OPEN; +@@ -74,7 +76,7 @@ reiserfs_open( struct boot_file_t *file, + memset( INFO, 0, sizeof(struct reiserfs_state) ); + INFO->file = file; + +- if (part) ++ if (fspec->part) + { + DEBUG_F( "Determining offset for partition %d\n", part->part_number ); + INFO->partition_offset = ((uint64_t)part->part_start) * part->blocksize; +diff -pur yaboot-1.3.14.orig/second/fs_xfs.c yaboot-1.3.14/second/fs_xfs.c +--- yaboot-1.3.14.orig/second/fs_xfs.c 2010-02-08 13:06:21.059432320 +1100 ++++ yaboot-1.3.14/second/fs_xfs.c 2010-02-08 13:07:31.972189749 +1100 +@@ -39,8 +39,8 @@ int xfs_read_data (char *buf, int len); + int xfs_dir (char *dirname); + + /* Exported in struct fs_t */ +-static int xfs_open(struct boot_file_t *file, const char *dev_name, +- struct partition_t *part, const char *file_name); ++static int xfs_open(struct boot_file_t *file, ++ struct partition_t *part, struct boot_fspec_t *fspec); + static int xfs_read(struct boot_file_t *file, unsigned int size, void *buffer); + static int xfs_seek(struct boot_file_t *file, unsigned int newpos); + static int xfs_close(struct boot_file_t *file); +@@ -59,8 +59,8 @@ uint64_t partition_offset; + int errnum; + + static int +-xfs_open(struct boot_file_t *file, const char *dev_name, +- struct partition_t *part, const char *file_name) ++xfs_open(struct boot_file_t *file, ++ struct partition_t *part, struct boot_fspec_t *fspec) + { + static char buffer[1024]; + +@@ -78,11 +78,11 @@ xfs_open(struct boot_file_t *file, const + else + partition_offset = 0; + +- strncpy(buffer, dev_name, 1020); ++ strncpy(buffer, fspec->dev, 1020); + if (_machine != _MACH_bplan) + strcat(buffer, ":0"); /* 0 is full disk in (non-buggy) OF */ + DEBUG_F("Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n", +- buffer, file_name, partition_offset); ++ buffer, fspec->file, partition_offset); + file->of_device = prom_open(buffer); + + if (file->of_device == PROM_INVALID_HANDLE || file->of_device == NULL) +@@ -105,8 +105,8 @@ xfs_open(struct boot_file_t *file, const + return FILE_ERR_BAD_FSYS; + } + +- DEBUG_F("Attempting to open %s\n", file_name); +- strcpy(buffer, file_name); /* xfs_dir modifies argument */ ++ DEBUG_F("Attempting to open %s\n", fspec->file); ++ strcpy(buffer, fspec->file); /* xfs_dir modifies argument */ + if(!xfs_dir(buffer)) + { + DEBUG_F("xfs_dir() failed. errnum = %d\n", errnum); +@@ -116,7 +116,7 @@ xfs_open(struct boot_file_t *file, const + return errnum; + } + +- DEBUG_F("Successfully opened %s\n", file_name); ++ DEBUG_F("Successfully opened %s\n", fspec->file); + + DEBUG_LEAVE(FILE_ERR_OK); + return FILE_ERR_OK; +diff -pur yaboot-1.3.14.orig/second/yaboot.c yaboot-1.3.14/second/yaboot.c +--- yaboot-1.3.14.orig/second/yaboot.c 2010-02-08 13:06:21.115436698 +1100 ++++ yaboot-1.3.14/second/yaboot.c 2010-02-08 13:07:31.975188101 +1100 +@@ -300,6 +300,7 @@ void print_message_file(char *filename) + } + + strncpy(msgpath, filename, sizeof(msgpath)); ++ msgfile = boot; /* Copy all the original paramters */ + if (!parse_device_path(msgpath, defdev, defpart, "/etc/yaboot.msg", &msgfile)) { + prom_printf("%s: Unable to parse\n", msgpath); + goto done; +@@ -988,6 +989,7 @@ int get_params(struct boot_param_t* para + if (!label && password) + check_password ("To boot a custom image you must enter the password."); + ++ params->kernel = boot; /* Copy all the original paramters */ + if (!parse_device_path(imagepath, defdevice, defpart, + "/vmlinux", ¶ms->kernel)) { + prom_printf("%s: Unable to parse\n", imagepath); +@@ -1009,6 +1011,7 @@ int get_params(struct boot_param_t* para + strncpy(initrdpath, p, 1024); + + DEBUG_F("Parsing initrd path <%s>\n", initrdpath); ++ params->rd = boot; /* Copy all the original paramters */ + if (!parse_device_path(initrdpath, defdevice, defpart, + "/root.bin", ¶ms->rd)) { + prom_printf("%s: Unable to parse\n", imagepath); +@@ -1019,6 +1022,7 @@ int get_params(struct boot_param_t* para + if (p && *p) { + DEBUG_F("Parsing sysmap path <%s>\n", p); + strncpy(sysmappath, p, 1024); ++ params->sysmap = boot; /* Copy all the original paramters */ + if (!parse_device_path(sysmappath, defdevice, defpart, + "/boot/System.map", ¶ms->sysmap)) { + prom_printf("%s: Unable to parse\n", imagepath); diff --git a/yaboot-1.3.14-better_netboot2.patch b/yaboot-1.3.14-better_netboot2.patch new file mode 100644 index 0000000..a3bb0f3 --- /dev/null +++ b/yaboot-1.3.14-better_netboot2.patch @@ -0,0 +1,316 @@ +diff -purN yaboot-1.3.14.orig/include/file.h yaboot-1.3.14/include/file.h +--- yaboot-1.3.14.orig/include/file.h 2009-10-15 11:39:01.112642471 +1100 ++++ yaboot-1.3.14/include/file.h 2009-10-15 15:29:04.692654961 +1100 +@@ -45,6 +45,7 @@ struct boot_fspec_t { + char* giaddr; /* Gateway address */ + char* bootp_retries; /* Bootp retries */ + char* tftp_retries; /* TFTP retries */ ++ char* subnetmask; /* Subnet mask */ + char* addl_params; /* copy all additional parameters */ + + /* Following fields are used only in ipv6 format */ +diff -purN yaboot-1.3.14.orig/include/prom.h yaboot-1.3.14/include/prom.h +--- yaboot-1.3.14.orig/include/prom.h 2009-10-15 15:23:39.796944672 +1100 ++++ yaboot-1.3.14/include/prom.h 2009-10-15 15:29:04.692654961 +1100 +@@ -153,7 +153,7 @@ struct bootp_packet { + unsigned char chaddr[16]; + unsigned char sname[64]; + unsigned char file[128]; +- /* vendor options go here if we need them */ ++ unsigned char options[]; /* vendor options */ + }; + + struct bootp_packet * prom_get_netinfo (void); +diff -purN yaboot-1.3.14.orig/second/cfg.c yaboot-1.3.14/second/cfg.c +--- yaboot-1.3.14.orig/second/cfg.c 2009-10-15 15:23:39.798647660 +1100 ++++ yaboot-1.3.14/second/cfg.c 2009-10-15 15:29:04.693668247 +1100 +@@ -597,6 +597,9 @@ int cfg_set_default_by_mac (char *mac_ad + char * label = NULL; + int haslabel = 0; + ++ if (mac_addr == NULL) ++ return 0; ++ + /* check if there is an image label equal to mac_addr */ + for (tmp = images; tmp; tmp = tmp->next) { + label = cfg_get_strg_i (tmp->table, "label"); +diff -purN yaboot-1.3.14.orig/second/file.c yaboot-1.3.14/second/file.c +--- yaboot-1.3.14.orig/second/file.c 2009-10-15 15:23:39.802647442 +1100 ++++ yaboot-1.3.14/second/file.c 2009-10-15 15:29:04.694645423 +1100 +@@ -51,6 +51,42 @@ ipv4_to_str(__u32 ip) + return buf; + } + ++/* FIXME: COMMENT */ ++static char * is_valid_ip_str(char *str) ++{ ++ int i; ++ long tmp; ++ __u32 ip = 0; ++ char *ptr=str, *endptr; ++ ++ if (str == NULL) ++ return NULL; ++ ++ for (i=0; i<4; i++, ptr = ++endptr) { ++ tmp = strtol(ptr, &endptr, 10); ++ if ((tmp & 0xff) != tmp) ++ return NULL; ++ ++ /* If we reach the end of the string but we're not in the 4th octet ++ * we have an invalid IP */ ++ if (*endptr == '\x0' && i!=3) ++ return NULL; ++ ++ /* If we have anything other than a NULL or '.' we have an invlaid ++ * IP */ ++ if (*endptr != '\x0' && *endptr != '.') ++ return NULL; ++ ++ ip += (tmp << (24-(i*8))); ++ } ++ ++ if (ip == 0 || ip == ~0u) ++ return NULL; ++ ++ return str; ++} ++ ++ + /* + * Copy the string from source to dest till newline or comma(,) is seen + * in the source. +@@ -130,12 +166,13 @@ extract_ipv4_args(char *imagepath, struc + * read the arguments in order: siaddr,filename,ciaddr,giaddr, + * bootp-retries,tftp-retries,addl_prameters + */ +- result->siaddr = scopy(&str, &args); ++ result->siaddr = is_valid_ip_str(scopy(&str, &args)); + result->file = scopy(&str, &args); +- result->ciaddr = scopy(&str, &args); +- result->giaddr = scopy(&str, &args); ++ result->ciaddr = is_valid_ip_str(scopy(&str, &args)); ++ result->giaddr = is_valid_ip_str(scopy(&str, &args)); + result->bootp_retries = scopy(&str, &args); + result->tftp_retries = scopy(&str, &args); ++ result->subnetmask = scopy(&str, &args); + if (*args) { + result->addl_params = strdup(args); + if (!result->addl_params) +@@ -144,6 +181,82 @@ extract_ipv4_args(char *imagepath, struc + return 1; + } + ++/* DHCP options */ ++enum dhcp_options { ++ DHCP_PAD = 0, ++ DHCP_NETMASK = 1, ++ DHCP_ROUTERS = 3, ++ DHCP_DNS = 6, ++ DHCP_END = 255, ++}; ++ ++#define DHCP_COOKIE 0x63825363 ++#define DHCP_COOKIE_SIZE 4 ++ ++/* ++ * FIXME: COMMENT ++ */ ++static void ++extract_vendor_options(struct bootp_packet *packet, struct boot_fspec_t *result) ++{ ++ int i = 0; ++ __u32 cookie; ++ __u8 *options = &packet->options[0]; ++ ++ memcpy(&cookie, &options[i], DHCP_COOKIE_SIZE); ++ ++ if (cookie != DHCP_COOKIE) { ++ prom_printf("EEEK! cookie is fubar got %08x expected %08x\n", ++ cookie, DHCP_COOKIE); ++ return; ++ } ++ ++ i += DHCP_COOKIE_SIZE; ++ ++ /* FIXME: It may be possible to run off the end of a packet here /if/ ++ * it's malformed. :( */ ++ while (options[i] != DHCP_END) { ++ __u8 tag = options[i++], len; ++ __u32 value; ++ ++ if (tag == DHCP_PAD) ++ continue; ++ ++ len = options[i++]; ++ memcpy(&value, &options[i], len); ++ ++#if DEBUG ++{ ++ DEBUG_F("tag=%2d, len=%2d, data=", tag, len); ++ int j; ++ for (j=0; jsubnetmask == NULL || *(result->subnetmask) == '\x0') && value != 0) { ++ result->subnetmask = ipv4_to_str(value); ++ DEBUG_F("Storing %s as subnetmask from options\n", ++ result->subnetmask); ++ } ++ /* FIXME: do we need to grok the subnet mask? */ ++ break; ++ case DHCP_ROUTERS: ++ if ((result->giaddr == NULL || *(result->giaddr) == '\x0') ++ && value != 0) { ++ result->giaddr = ipv4_to_str(value); ++ DEBUG_F("Storing %s as gateway from options\n", ++ result->giaddr); ++ } ++ break; ++ } ++ i += len; ++ } ++} ++ + /* + * Check netinfo for ipv4 parameters and add them to the fspec iff the + * fspec has no existing value. +@@ -170,16 +283,18 @@ extract_netinfo_args(struct boot_fspec_t + if (packet->ciaddr == 0 && packet->yiaddr != 0) + packet->ciaddr = packet->yiaddr; + +- if ((result->siaddr == NULL || *(result->siaddr) == NULL) ++ if ((result->siaddr == NULL || *(result->siaddr) == '\x0') + && packet->siaddr != 0) + result->siaddr = ipv4_to_str(packet->siaddr); +- if ((result->ciaddr == NULL || *(result->ciaddr) == NULL) ++ if ((result->ciaddr == NULL || *(result->ciaddr) == '\x0') + && packet->ciaddr != 0) + result->ciaddr = ipv4_to_str(packet->ciaddr); +- if ((result->giaddr == NULL || *(result->giaddr) == NULL) ++ if ((result->giaddr == NULL || *(result->giaddr) == '\x0') + && packet->giaddr != 0) + result->giaddr = ipv4_to_str(packet->giaddr); + ++ extract_vendor_options(packet, result); ++ + /* FIXME: Yck! if we /still/ do not have a gateway then "cheat" and use + * the server. This will be okay if the client and server are on + * the same IP network, if not then lets hope the server does ICMP +diff -purN yaboot-1.3.14.orig/second/fs_of.c yaboot-1.3.14/second/fs_of.c +--- yaboot-1.3.14.orig/second/fs_of.c 2009-10-15 15:23:39.805647069 +1100 ++++ yaboot-1.3.14/second/fs_of.c 2009-10-15 15:29:04.695645439 +1100 +@@ -137,6 +137,7 @@ of_net_open(struct boot_file_t* file, + static char buffer[1024]; + char *filename = NULL; + char *p; ++ int new_tftp; + + DEBUG_ENTER; + DEBUG_OPEN; +@@ -148,34 +149,47 @@ of_net_open(struct boot_file_t* file, + *p = '\\'; + } + +- DEBUG_F("siaddr <%s>; filename <%s>; ciaddr <%s>; giaddr <%s>; ipv6 <%d>\n", +- fspec->siaddr, filename, fspec->ciaddr, fspec->giaddr, fspec->is_ipv6); ++ DEBUG_F("siaddr <%s>; filename <%s>; ciaddr <%s>; giaddr <%s>;" ++ " ipv6 <%d>\n", ++ fspec->siaddr, filename, fspec->ciaddr, fspec->giaddr, ++ fspec->is_ipv6); ++ + strncpy(buffer, fspec->dev, 768); + if (fspec->is_ipv6) + strcat(buffer, TOK_IPV6 ","); +- /* If we didn't get a ':' include one */ +- if (fspec->dev[strlen(fspec->dev)-1] != ':') ++ else if (fspec->dev[strlen(fspec->dev)-1] != ':') + strcat(buffer, ":"); +- strcat(buffer, fspec->siaddr); +- strcat(buffer, ","); +- if (fspec->is_ipv6 && (strstr(filename, "filename=") == NULL)) +- strcat(buffer, "filename="); +- strcat(buffer, filename); +- strcat(buffer, ","); +- strcat(buffer, fspec->ciaddr); +- strcat(buffer, ","); +- strcat(buffer, fspec->giaddr); + +- /* If /packages/cas exists the we have a "new skool" tftp */ +- if (prom_finddevice("/packages/cas") != PROM_INVALID_HANDLE) { ++ /* If /packages/cas exists the we have a "new skool" tftp. ++ * This means that siaddr is the tftp server and that we can add ++ * {tftp,bootp}_retrys, subnet mask and tftp block size to the load ++ * method */ ++ new_tftp = (prom_finddevice("/packages/cas") != PROM_INVALID_HANDLE); ++ DEBUG_F("Using %s tftp style\n", (new_tftp? "new": "old")); ++ ++ if (new_tftp) { ++ strcat(buffer, fspec->siaddr); ++ strcat(buffer, ","); ++ ++ if (fspec->is_ipv6 && (strstr(filename, "filename=") == NULL)) ++ strcat(buffer, "filename="); ++ ++ strcat(buffer, filename); ++ strcat(buffer, ","); ++ strcat(buffer, fspec->ciaddr); + strcat(buffer, ","); ++ strcat(buffer, fspec->giaddr); ++ strcat(buffer, ","); + strcat(buffer, fspec->bootp_retries); + strcat(buffer, ","); + strcat(buffer, fspec->tftp_retries); + strcat(buffer, ","); ++ strcat(buffer, fspec->subnetmask); ++ strcat(buffer, ","); + strcat(buffer, fspec->addl_params); + } else { +- DEBUG_F("No \"/packages/cas\" using simple args\n") ++ strcat(buffer, ","); ++ strcat(buffer, filename); + } + + DEBUG_F("Opening: \"%s\"\n", buffer); +diff -purN yaboot-1.3.14.orig/second/prom.c yaboot-1.3.14/second/prom.c +--- yaboot-1.3.14.orig/second/prom.c 2009-10-15 15:23:39.806647224 +1100 ++++ yaboot-1.3.14/second/prom.c 2009-10-15 15:29:04.696645314 +1100 +@@ -685,6 +685,10 @@ struct bootp_packet * prom_get_netinfo ( + void *bootp_response = NULL; + char *propname; + struct bootp_packet *packet; ++ /* struct bootp_packet contains a VLA, so sizeof won't work. ++ the VLA /must/ be the last field in the structure so use it's ++ offset as a good estimate of the packet size */ ++ size_t packet_size = offsetof(struct bootp_packet, options); + int i = 0, size, offset = 0; + prom_handle chosen; + #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +@@ -709,7 +713,7 @@ struct bootp_packet * prom_get_netinfo ( + if (size <= 0) + return NULL; + +- if (sizeof(*packet) > size - offset) { ++ if (packet_size > size - offset) { + prom_printf("Malformed %s property?\n", propname); + return NULL; + } +diff -purN yaboot-1.3.14.orig/second/yaboot.c yaboot-1.3.14/second/yaboot.c +--- yaboot-1.3.14.orig/second/yaboot.c 2009-10-15 15:23:39.809646432 +1100 ++++ yaboot-1.3.14/second/yaboot.c 2009-10-15 15:29:04.697642396 +1100 +@@ -471,6 +471,10 @@ static int load_my_config_file(struct bo + int minlen; + + packet = prom_get_netinfo(); ++ if (packet == NULL) { ++ prom_printf("Failed to get netinfo data\n"); ++ return 0; ++ } + + /* + * First, try to match on mac address with the hardware type diff --git a/yaboot-1.3.14-bigger-max-token.patch b/yaboot-1.3.14-bigger-max-token.patch new file mode 100644 index 0000000..b1a7d32 --- /dev/null +++ b/yaboot-1.3.14-bigger-max-token.patch @@ -0,0 +1,12 @@ +diff -up yaboot-1.3.14/second/cfg.c.bigger-max-token yaboot-1.3.14/second/cfg.c +--- yaboot-1.3.14/second/cfg.c.bigger-max-token 2008-11-12 14:39:11.000000000 -0500 ++++ yaboot-1.3.14/second/cfg.c 2008-11-12 14:39:17.000000000 -0500 +@@ -41,7 +41,7 @@ typedef struct { + void *data; + } CONFIG; + +-#define MAX_TOKEN 200 ++#define MAX_TOKEN 511 + #define MAX_VAR_NAME MAX_TOKEN + #define EOF -1 + diff --git a/yaboot-1.3.14-dont_of_open_native_partitions.patch b/yaboot-1.3.14-dont_of_open_native_partitions.patch new file mode 100644 index 0000000..048349b --- /dev/null +++ b/yaboot-1.3.14-dont_of_open_native_partitions.patch @@ -0,0 +1,15 @@ +diff -urNp yaboot-1.3.14.orig/second/fs_of.c yaboot-1.3.14/second/fs_of.c +--- yaboot-1.3.14.orig/second/fs_of.c 2009-10-14 09:39:46.263661071 +1100 ++++ yaboot-1.3.14/second/fs_of.c 2009-10-14 09:43:42.932691139 +1100 +@@ -92,8 +92,8 @@ of_open(struct boot_file_t* file, + strncpy(buffer, fspec->dev, 768); + strcat(buffer, ":"); + if (part) { +- if (part->sys_ind == LINUX_RAID) { +- DEBUG_F("skipping because partition is marked LINUX_RAID\n"); ++ if (part->sys_ind == LINUX_RAID || part->sys_ind == LINUX_NATIVE) { ++ DEBUG_F("skipping because partition is marked %x\n", part->sys_ind); + DEBUG_LEAVE(FILE_ERR_BAD_FSYS); + return FILE_ERR_BAD_FSYS; + } +Binary files yaboot-1.3.14.orig/second/.fs_of.c.swp and yaboot-1.3.14/second/.fs_of.c.swp differ diff --git a/yaboot-1.3.14-fix-bootonce-nvram.patch b/yaboot-1.3.14-fix-bootonce-nvram.patch new file mode 100644 index 0000000..c7d20ba --- /dev/null +++ b/yaboot-1.3.14-fix-bootonce-nvram.patch @@ -0,0 +1,21 @@ +diff -up yaboot-1.3.14/ybin/ybin.fix-bootonce-nvram yaboot-1.3.14/ybin/ybin +--- yaboot-1.3.14/ybin/ybin.fix-bootonce-nvram 2008-11-12 14:51:28.000000000 -0500 ++++ yaboot-1.3.14/ybin/ybin 2008-11-13 12:15:21.000000000 -0500 +@@ -1689,14 +1689,15 @@ checkconf || exit 1 + + if [ "x$bootonce" != "x" ]; then + foundlabel=`sed s/\#.*// $bootconf | grep "label=$bootonce$" | wc -l` +- if [ "$nonvram" = 0 ]; then ++ if [ "$nonvram" = 1 ]; then + echo 1>&2 "$PRG: --bootonce specified, but nvsetenv not available." + exit 1 + fi + if [ "$foundlabel" = 1 ]; then + nvsetenv boot-once "$bootonce" + foundlabel=`nvsetenv boot-once` +- if [ "$foundlabel" != "boot-once=$bootonce" ]; then ++ if [ "$foundlabel" != "boot-once=$bootonce" -a \ ++ "$foundlabel" != "$bootonce" ]; then + echo 1>&2 "$PRG: Could not nvsetenv boot-once $bootonce" + exit 1 + fi diff --git a/yaboot-1.3.14-gitpatches.patch b/yaboot-1.3.14-gitpatches.patch new file mode 100644 index 0000000..c7acb93 --- /dev/null +++ b/yaboot-1.3.14-gitpatches.patch @@ -0,0 +1,725 @@ +commit 37578220a9120f0a7770b0c6c6eae046ce72fc93 +Author: David Woodhouse +Date: Fri Mar 28 00:04:02 2008 +0000 + + Pegasos and partition numbering + + The whole bplan partition numbering thing is a clusterfuck, but it + shouldn't be as crappy as it is. + + We can _cope_ with the fact that firmware is broken and has an + off-by-one in its partition numbering. All we need to do in yaboot is + add 1 to the partition numbers we infer from in /chosen/boot-device, if + we detect that we're on an afflicted machine. That's all we need to do, + and all we ever _should_ have done. And is already in yaboot. Yaboot + does its own block device handling, including partitions, and doesn't + ever care about the firmware's problems (in that respect, at least). + + It doesn't affect the installer at _all_, because the installer can't + set up the firmware's boot-device anyway and it has to be done by hand. + All it affects is the release notes telling the user how to make it + bootable. + + Unfortunately, we didn't make it that simple when we first supported the + Pegasos. For reasons which aren't entirely clear to me, we ended up with + Amiga partition table support in yaboot with the _same_ off-by-one + error, to match the firmware. And thus we have hacks in the installer to + use amiga partitions for Pegasos, and to cope with the off-by-one crap. + + It's only after avoiding all this crap purely by accident on Efika, by + using DOS partition tables, that I realise how stupid I was to blindly + copy the crap that other people were doing, and to believe that Pegasos + would only work with Amiga partition tables. + + I'd like to get rid of the off-by-one bug in yaboot's Amiga partition + handling. At the moment, our simple 'if bplan, partition++' in + yaboot_main() is wrong when we have Amiga partitions, although it's fine + for other partition types. + + Actually, I'd also like to make that same increment conditional on + !conf_given, so that if someone specifies 'conf=hd:1,/yaboot.conf' on + the command line, that partition number _isn't_ incremented. + + So any time you see a proper path specified as 'dev:part,/path/name' you + know it's a real one with proper partition numbers. Remember, the bplan + firmware doesn't allow that form, and takes a space between the + 'dev:part' bit and the filename: + boot hd:0 /yaboot/yaboot conf=hd:1,/yaboot/yaboot.conf + + Fixing the off-by-one bug in the Amiga partition handling means that + upgrades might break. I suppose we could have a 'noamigaoffbyone' + configuration option which all newly-written yaboot.conf files would + have, which controls this behaviour. But to be honest I just don't think + it's worth it. + +commit 0c0a18b7a1a6b44963da4469d21428e76f9c2b30 +Author: Mike Wolf +Date: Tue Jan 15 14:33:51 2008 -0600 + + use public interface to detect CAS reboots (take 2) + + This is the second pass of this patch. The fw variable name is changed + to use ibm,client-architecture-support-reboot field which is already present + in the firmware. Please disregard the previous patch. + + The firmware field used to detect CAS reboots (ibm,fw-nbr-reboots) is + really a private field that could change without warning. A new field + ibm,#reconfig-reboots will be added as a public interface intended to + be used for this detection. The patch will first check for + ibm,client-architecture-support-reboot if that is not found it will see + if ibm,fw-nbr-reboots is present and will use that instead. + + ------- + +commit 526b77920b050e1e37e842e8def4a5e7fb04cee6 +Author: Paul Nasrat +Date: Fri Jan 4 13:00:19 2008 +0000 + + The CAS (Client-Architecture Support) call tells firmware what capabilities the + OS has. These capabilities result in different modes which the device-tree is + configured in, as well as what processor capabilities are presented. So, if + the capabilities are different from what was previously booted, firmware has to + reboot to reconfigure the device-tree. The second boot will have the updated + device-tree and we can boot as normal. + + When this firmware initiated reboot occurs yaboot will now boot the same kernel + as the previous boot attempt with no action by the user needed. I have + successfully booted on POWER5 and POWER6 machines using various levels of the + kernel. + + Patch from: Mike Wolf + +commit f843e296a197cc94c0e0f80d49a67dc71c6785a2 +Author: Paul Nasrat +Date: Thu Jan 3 19:21:44 2008 +0000 + + Revert "The attached patch adds support for writing the nvram using the nvram" + + This reverts commit ac8fbd5ad52b43b820973f1828a29f85bed13a1d. + +commit 50b58606fb2d11aa6548d1fec606275c33a930c7 +Author: Paul Nasrat +Date: Thu Jan 3 19:21:22 2008 +0000 + + Revert "Fix shell syntax" + + This reverts commit 24679e706305e0910f181a9640b8b88a30662d03. + +commit 24679e706305e0910f181a9640b8b88a30662d03 +Author: Paul Nasrat +Date: Thu Jan 3 19:07:50 2008 +0000 + + Fix shell syntax + +commit ac8fbd5ad52b43b820973f1828a29f85bed13a1d +Author: Paul Nasrat +Date: Tue Dec 4 08:43:32 2007 +0000 + + The attached patch adds support for writing the nvram using the nvram + utility from the new powerpc-utils pkg from IBM; it also simplify a bit + the code. + + Patch from: Emanuele Giaquinta (exg@gentoo.org) + +commit 131e44d7e0bf592eaa8214e684fef38bf654410a +Author: Paul Nasrat +Date: Mon Dec 3 14:21:11 2007 +0000 + + Force build to be ppc32 + +commit ff0e80c9b39b18a907d1f1ffb8f836b13af4ebb1 +Author: Paul Nasrat +Date: Mon Dec 3 14:14:42 2007 +0000 + + Fix typo + +commit 66ffb9d32d2acb3613594ef492d341b5bacf02e5 +Author: Paul Nasrat +Date: Mon Dec 3 14:13:54 2007 +0000 + + Fix typo in patch porting + +commit 082b8310e3f92ea8da0b7011549bd86c9fd4ce95 +Author: Paul Nasrat +Date: Mon Dec 3 14:05:48 2007 +0000 + + Fix partition numbering handling with bplan firmware + Patch based on Fedora patch by dwmw2@infradead.org + +commit afaf577190536fe8e15fb5b2ed8372dbda82e7b1 +Author: Paul Nasrat +Date: Mon Dec 3 13:17:33 2007 +0000 + + Try harder to allocate malloc region + Patch from dwmw2@infradead.org + +commit 752525a7feb16e02b759ca7811fc9a0276712c3d +Author: Paul Nasrat +Date: Mon Dec 3 13:13:23 2007 +0000 + + Print version-release of yaboot + Patch from dwmw2@infradead.org + +commit c8b04c614770870d75825c19bcd4729cc779b84a +Author: Paul Nasrat +Date: Mon Dec 3 13:04:19 2007 +0000 + + Let prom_claim_chunk do the work for tftp images to support larger images. + + Patch from: Leonardo Rangel + +commit b6b70ff54df42432d58801ac69ba24e7d95e0426 +Author: Paul Nasrat +Date: Mon Dec 3 12:41:42 2007 +0000 + + These patch provides the function of load a alternative initrd file + specified by the user via Yaboot prompt. To load the new file, just use + the "initrd=" command. The could include + all the directory path to the file. + + Using only the "initrd" command, Yaboot will load the default kernel + specified in the configuration file and the initrd file specified by the + user. The user can, also, specify an initrd file to any other label of + the configuration file, just adding the "initrd" command before the + label's name. + + Signed-off-by: Paulo Ricardo Paz Vital + +commit 4ba173298fa8630628c9014028fccc22e511d48a +Author: Paul Nasrat +Date: Mon Dec 3 12:39:06 2007 +0000 + + move the tftp load space and use prom_claim_chunk to claim the memory. + Growing kernels mean that the 6MB that was allotted is not enough. + + Patch from Scott Moser + +commit f3d8af0e0ac4642499d5430c202ac57d1d4c5ceb +Author: Paul Nasrat +Date: Mon Dec 3 12:37:10 2007 +0000 + + The patch from Scott Moser moves the "search-for-prom_claim'able" routine that + was present in load_elf64 and load_elf32 to a function named + prom_claim_chunk. This reduces the code-snippit duplication and makes + the function available for of_net_open. + + Scott Moser ssmoser@us.ibm.com +-------------------------------------------------------------------------------- +diff --git a/Makefile b/Makefile +index ce0dc06..fe2f2fd 100644 +--- a/Makefile ++++ b/Makefile +@@ -21,7 +21,7 @@ TEXTADDR = 0x200000 + MALLOCADDR = 0x300000 + MALLOCSIZE = 0x100000 + # Load kernel and ramdisk at real-base. If there is overlap, will retry until find open space +-KERNELADDR = 0x00C00000 ++KERNELADDR = 0x00000000 + + # Set this to the prefix of your cross-compiler, if you have one. + # Else leave it empty. +@@ -35,8 +35,8 @@ OBJCOPY := $(CROSS)objcopy + + # The flags for the yaboot binary. + # +-YBCFLAGS = -Os $(CFLAGS) -nostdinc -Wall -isystem `$(CC) -print-file-name=include` -fsigned-char +-YBCFLAGS += -DVERSION=\"${VERSION}\" #" ++YBCFLAGS = -Os $(CFLAGS) -nostdinc -Wall -isystem `$(CC) -m32 -print-file-name=include` -fsigned-char ++YBCFLAGS += -DVERSION="\"${VERSION}${VERSIONEXTRA}\"" #" + YBCFLAGS += -DTEXTADDR=$(TEXTADDR) -DDEBUG=$(DEBUG) + YBCFLAGS += -DMALLOCADDR=$(MALLOCADDR) -DMALLOCSIZE=$(MALLOCSIZE) + YBCFLAGS += -DKERNELADDR=$(KERNELADDR) +@@ -64,7 +64,7 @@ endif + + # Link flags + # +-LFLAGS = -Ttext $(TEXTADDR) -Bstatic ++LFLAGS = -Ttext $(TEXTADDR) -Bstatic -melf32ppclinux + + # Libraries + # +@@ -99,7 +99,7 @@ OBJS += second/fs_reiserfs.o + endif + + # compilation +-lgcc = `$(CC) -print-libgcc-file-name` ++lgcc = `$(CC) -m32 -print-libgcc-file-name` + + all: yaboot addnote mkofboot + +diff --git a/include/bootinfo.h b/include/bootinfo.h +index f61409a..7602e48 100644 +--- a/include/bootinfo.h ++++ b/include/bootinfo.h +@@ -34,6 +34,7 @@ + #define _MACH_classic 0x00000400 /* RPCG RPX-Classic 8xx board */ + #define _MACH_oak 0x00000800 /* IBM "Oak" 403 eval. board */ + #define _MACH_walnut 0x00001000 /* IBM "Walnut" 405GP eval. board */ ++#define _MACH_bplan 0x00002000 /* Pegasos/Efika, broken partition #s */ + + struct bi_record { + unsigned long tag; /* tag ID */ +@@ -51,6 +52,8 @@ struct bi_record { + + #endif /* _PPC_BOOTINFO_H */ + ++extern int _machine; ++ + /* + * Local variables: + * c-file-style: "k&r" +diff --git a/include/prom.h b/include/prom.h +index f5ee88f..eacee77 100644 +--- a/include/prom.h ++++ b/include/prom.h +@@ -37,6 +37,9 @@ typedef void *phandle; + #define PROM_INVALID_HANDLE ((prom_handle)-1UL) + #define BOOTDEVSZ (2048) /* iscsi args can be in excess of 1040 bytes */ + #define TOK_ISCSI "iscsi" ++#define PROM_CLAIM_MAX_ADDR 0x8000000 ++#define BOOTLASTSZ 1024 ++#define FW_NBR_REBOOTSZ 4 + + struct prom_args; + typedef int (*prom_entry)(struct prom_args *); +@@ -85,6 +88,7 @@ int prom_set_color(prom_handle device, int color, int r, int g, int b); + + /* memory */ + ++void *prom_claim_chunk(void *virt, unsigned int size, unsigned int align); + void *prom_claim (void *virt, unsigned int size, unsigned int align); + void prom_release(void *virt, unsigned int size); + void prom_map (void *phys, void *virt, int size); +diff --git a/second/fs_ext2.c b/second/fs_ext2.c +index 3240ce2..67571f2 100644 +--- a/second/fs_ext2.c ++++ b/second/fs_ext2.c +@@ -35,6 +35,7 @@ + #include "fs.h" + #include "errors.h" + #include "debug.h" ++#include "bootinfo.h" + + #define FAST_VERSION + #define MAX_READ_RANGE 256 +@@ -170,7 +171,8 @@ ext2_open( struct boot_file_t* file, + + /* Open the OF device for the entire disk */ + strncpy(buffer, dev_name, 1020); +- strcat(buffer, ":0"); ++ if (_machine != _MACH_bplan) ++ strcat(buffer, ":0"); + + DEBUG_F("<%s>\n", buffer); + +diff --git a/second/fs_of.c b/second/fs_of.c +index 76474ee..0d554c5 100644 +--- a/second/fs_of.c ++++ b/second/fs_of.c +@@ -44,9 +44,8 @@ + #include "errors.h" + #include "debug.h" + +-#define LOAD_BUFFER_POS 0x600000 +-/* this cannot be safely increased any further */ +-#define LOAD_BUFFER_SIZE 0x600000 ++#define LOAD_BUFFER_POS 0x00000000 ++#define LOAD_BUFFER_SIZE 0x01000000 + + static int of_open(struct boot_file_t* file, const char* dev_name, + struct partition_t* part, const char* file_name); +@@ -166,7 +165,9 @@ of_net_open(struct boot_file_t* file, const char* dev_name, + return FILE_ERR_BAD_FSYS; + } + +- file->buffer = prom_claim((void *)LOAD_BUFFER_POS, LOAD_BUFFER_SIZE, 0); ++ ++ file->buffer = prom_claim_chunk((void *)LOAD_BUFFER_POS, ++ LOAD_BUFFER_SIZE, 0); + if (file->buffer == (void *)-1) { + prom_printf("Can't claim memory for TFTP download\n"); + prom_close(file->of_device); +diff --git a/second/fs_reiserfs.c b/second/fs_reiserfs.c +index 4ad1c2e..238f523 100644 +--- a/second/fs_reiserfs.c ++++ b/second/fs_reiserfs.c +@@ -29,6 +29,7 @@ + #include "fs.h" + #include "errors.h" + #include "debug.h" ++#include "bootinfo.h" + #include "reiserfs/reiserfs.h" + + /* Exported in struct fs_t */ +@@ -84,7 +85,10 @@ reiserfs_open( struct boot_file_t *file, const char *dev_name, + else + INFO->partition_offset = 0; + +- sprintf( buffer, "%s:%d", dev_name, 0 ); /* 0 is full disk in OF */ ++ strncpy(buffer, dev_name, 1020); ++ if (_machine != _MACH_bplan) ++ strcat(buffer, ":0"); /* 0 is full disk in (non-buggy) OF */ ++ + file->of_device = prom_open( buffer ); + DEBUG_F( "Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n", + buffer, file_name, INFO->partition_offset ); +diff --git a/second/fs_xfs.c b/second/fs_xfs.c +index 9a2aaa6..04d6cf3 100644 +--- a/second/fs_xfs.c ++++ b/second/fs_xfs.c +@@ -30,6 +30,7 @@ + #include "xfs/xfs.h" + #include "errors.h" + #include "debug.h" ++#include "bootinfo.h" + + #define SECTOR_BITS 9 + +@@ -77,7 +78,9 @@ xfs_open(struct boot_file_t *file, const char *dev_name, + else + partition_offset = 0; + +- sprintf(buffer, "%s:%d", dev_name, 0); /* 0 is full disk in OF */ ++ strncpy(buffer, dev_name, 1020); ++ if (_machine != _MACH_bplan) ++ strcat(buffer, ":0"); /* 0 is full disk in (non-buggy) OF */ + DEBUG_F("Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n", + buffer, file_name, partition_offset); + file->of_device = prom_open(buffer); +diff --git a/second/partition.c b/second/partition.c +index 0cb8ae8..d20a0ed 100644 +--- a/second/partition.c ++++ b/second/partition.c +@@ -40,6 +40,7 @@ + #include "linux/iso_fs.h" + #include "debug.h" + #include "errors.h" ++#include "bootinfo.h" + #include "byteorder.h" + + /* We currently don't check the partition type, some users +@@ -286,7 +287,7 @@ partition_amiga_lookup( const char *dev_name, prom_handle disk, + for (i=0; i < possible; i++) used[i] = 0; + + +- for (part = amiga_block[AMIGA_PARTITIONS], partition = 0; ++ for (part = amiga_block[AMIGA_PARTITIONS], partition = 1; + part != AMIGA_END; + part = amiga_block[AMIGA_PART_NEXT], partition++) + { +@@ -337,7 +338,8 @@ partitions_lookup(const char *device) + unsigned int prom_blksize, iso_root_block; + + strncpy(block_buffer, device, 2040); +- strcat(block_buffer, ":0"); ++ if (_machine != _MACH_bplan) ++ strcat(block_buffer, ":0"); + + /* Open device */ + disk = prom_open(block_buffer); +diff --git a/second/prom.c b/second/prom.c +index e9c5843..4ad7277 100644 +--- a/second/prom.c ++++ b/second/prom.c +@@ -568,6 +568,25 @@ prom_sleep (int seconds) + while (prom_getms() <= end); + } + ++/* if address given is claimed look for other addresses to get the needed ++ * space before giving up ++ */ ++void * ++prom_claim_chunk(void *virt, unsigned int size, unsigned int align) ++{ ++ void *found, *addr; ++ for(addr=virt; addr <= (void*)PROM_CLAIM_MAX_ADDR; ++ addr+=(0x100000/sizeof(addr))) { ++ found = prom_claim(addr, size, 0); ++ if (found != (void *)-1) { ++ DEBUG_F("claimed %i at 0x%x (0x%x)\n",size,(int)found,(int)virt); ++ return(found); ++ } ++ } ++ prom_printf("Claim error, can't allocate %x at 0x%x\n",size,(int)virt); ++ return((void*)-1); ++} ++ + void * + prom_claim (void *virt, unsigned int size, unsigned int align) + { +diff --git a/second/yaboot.c b/second/yaboot.c +index 0232d33..d6e8017 100644 +--- a/second/yaboot.c ++++ b/second/yaboot.c +@@ -114,6 +114,9 @@ int useconf = 0; + char bootdevice[BOOTDEVSZ]; + char bootoncelabel[1024]; + char bootargs[1024]; ++char bootlastlabel[BOOTLASTSZ] = {0}; ++char fw_nbr_reboots[FW_NBR_REBOOTSZ] = {0}; ++long fw_reboot_cnt = 0; + char *password = NULL; + struct boot_fspec_t boot; + int _machine = _MACH_Pmac; +@@ -178,6 +181,7 @@ yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5) + { + int result; + void* malloc_base = NULL; ++ unsigned long addr; + prom_handle root; + + /* OF seems to do it, but I'm not very confident */ +@@ -196,7 +200,10 @@ yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5) + prom_init ((prom_entry) r5); + + /* Allocate some memory for malloc'ator */ +- malloc_base = prom_claim((void *)MALLOCADDR, MALLOCSIZE, 0); ++ for (addr = MALLOCADDR; addr <= MALLOCADDR * 16 ;addr+=0x100000) { ++ malloc_base = prom_claim((void *)addr, MALLOCSIZE, 0); ++ if (malloc_base != (void *)-1) break; ++ } + if (malloc_base == (void *)-1) { + prom_printf("Can't claim malloc buffer (%d bytes at 0x%08x)\n", + MALLOCSIZE, MALLOCADDR); +@@ -219,7 +226,10 @@ yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5) + root = prom_finddevice("/"); + if (root != 0) { + static char model[256]; +- if (prom_getprop(root, "device_type", model, 256 ) > 0 && ++ if (prom_getprop(root, "CODEGEN,vendor", model, 256) > 0 && ++ !strncmp("bplan", model, 5)) ++ _machine = _MACH_bplan; ++ else if (prom_getprop(root, "device_type", model, 256 ) > 0 && + !strncmp("chrp", model, 4)) + _machine = _MACH_chrp; + else { +@@ -455,7 +465,7 @@ static int load_my_config_file(struct boot_fspec_t *orig_fspec) + struct bootp_packet *packet; + int rc = 0; + struct boot_fspec_t fspec = *orig_fspec; +- char *cfgpath = (_machine == _MACH_chrp) ? "/etc/" : ""; ++ char *cfgpath = (_machine == _MACH_chrp || _machine == _MACH_bplan) ? "/etc/" : ""; + int flen; + int minlen; + +@@ -654,6 +664,8 @@ int get_params(struct boot_param_t* params) + static char imagepath[1024]; + static char initrdpath[1024]; + static char sysmappath[1024]; ++ static char manualinitrd[1024]; ++ static int definitrd = 1, hasarg = 0; + + pause_after = 0; + memset(params, 0, sizeof(*params)); +@@ -665,7 +677,7 @@ int get_params(struct boot_param_t* params) + + cmdinit(); + +- if (first) { ++ if (first && !fw_reboot_cnt) { + first = 0; + imagename = bootargs; + word_split(&imagename, ¶ms->args); +@@ -680,6 +692,13 @@ int get_params(struct boot_param_t* params) + timeout = simple_strtol(q, NULL, 0); + } + ++ /* If this is a reboot due to FW detecting CAS changes then ++ * set timeout to 1. The last kernel booted will be booted ++ * again automatically. It should seem seamless to the user ++ */ ++ if (fw_reboot_cnt) ++ timeout = 1; ++ + prom_printf("boot: "); + c = -1; + if (timeout != -1) { +@@ -716,7 +735,9 @@ int get_params(struct boot_param_t* params) + if (!imagename) { + if (bootoncelabel[0] != 0) + imagename = bootoncelabel; +- else ++ else if (bootlastlabel[0] != 0) ++ imagename = bootlastlabel; ++ else + imagename = cfg_get_default(); + } + if (imagename) +@@ -733,10 +754,53 @@ int get_params(struct boot_param_t* params) + word_split(&imagename, ¶ms->args); + } + ++ /* initrd setup via cmd console */ ++ /* first, check if the user uses it with some label */ ++ if (!strncmp(params->args, "initrd=", 7)) { ++ DEBUG_F("params->args: %s\n", params->args); ++ definitrd = 0; ++ } ++ /* after, check if there is the 'initrd=' in the imagename string */ ++ if (!strncmp(imagename, "initrd=", 7) || !definitrd) { ++ ++ /* return the value of definitrd to 1 */ ++ if (!definitrd) ++ definitrd = 1; ++ ++ /* args = "initrd=blah" */ ++ char *args = NULL; ++ ++ if (params->args) { ++ args = params->args; ++ params->args = NULL; ++ hasarg = 1; ++ } else ++ args = imagename; ++ ++ if (strlen(args)){ ++ /* copy the string after the '=' to manualinitrd */ ++ strcpy(manualinitrd, args+7); ++ definitrd = 0; ++ prom_printf("New initrd file specified: %s\n", manualinitrd); ++ } else { ++ prom_printf("ERROR: no initrd specified!\n"); ++ return 0; ++ } ++ ++ /* set imagename with the default values of the config file */ ++ if ((prom_get_devtype(boot.dev) == FILE_DEVICE_NET) && !hasarg) ++ imagename = cfg_get_default(); ++ else ++ imagename = cfg_get_default(); ++ } ++ + /* chrp gets this wrong, force it -- Cort */ + if ( useconf && (!imagename || imagename[0] == 0 )) + imagename = cfg_get_default(); + ++ /* write the imagename out so it can be reused on reboot if necessary */ ++ prom_set_options("boot-last-label", imagename, strlen(imagename)); ++ + label = 0; + defdevice = boot.dev; + +@@ -794,6 +858,12 @@ int get_params(struct boot_param_t* params) + "resides on, and \"partno\" is the partition number the image resides on.\n" + "Note that the comma (,) is only required if you specify an OpenFirmware\n" + "device, if you only specify a filename you should not start it with a \",\"\n\n" ++ "To boot a alternative initrd file rather than specified in the yaboot\n" ++ "configuration file, use the \"initrd\" command on Yaboot's prompt: \n" ++ "\"initrd=[name.img]\". This will load the \"name.img\" file after the default\n" ++ "kernel image. You can, also, specify a different initrd file to any other\n" ++ "label of the yaboot configuration file. Just type \"label initrd=[name.img]\"\n" ++ "and the specified initrd file will be loaded.\n\n" + "To load an alternative config file rather than /etc/yaboot.conf, enter\n" + "its device, partno and path, on Open Firmware Prompt:\n" + "boot conf=device:partno,/path/to/configfile\n." +@@ -923,14 +993,22 @@ int get_params(struct boot_param_t* params) + prom_printf("%s: Unable to parse\n", imagepath); + return 0; + } +- DEBUG_F("after parse_device_path: dev=%s part=%d file=%s\n", params->kernel.dev, +- params->kernel.part, params->kernel.file); +- ++ DEBUG_F("after parse_device_path: dev=%s part=%d file=%s\n", params->kernel.dev, params->kernel.part, params->kernel.file); + if (useconf) { + p = cfg_get_strg(label, "initrd"); + if (p && *p) { +- DEBUG_F("Parsing initrd path <%s>\n", p); +- strncpy(initrdpath, p, 1024); ++ ++ /* check if user seted to use a initrd file from boot console */ ++ if (!definitrd && p != manualinitrd) { ++ if (manualinitrd[0] != "/" && (prom_get_devtype(defdevice_bak) != FILE_DEVICE_NET)) { ++ strcpy(initrdpath, "/"); ++ strcat(initrdpath, manualinitrd); ++ } else ++ strncpy(initrdpath, manualinitrd, 1024); ++ } else ++ strncpy(initrdpath, p, 1024); ++ ++ DEBUG_F("Parsing initrd path <%s>\n", initrdpath); + if (!parse_device_path(initrdpath, defdevice, defpart, + "/root.bin", ¶ms->rd)) { + prom_printf("%s: Unable to parse\n", imagepath); +@@ -1233,7 +1311,7 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo) + Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr); + Elf32_Phdr *p, *ph; + int size = sizeof(Elf32_Ehdr) - sizeof(Elf_Ident); +- unsigned long addr, loadaddr; ++ unsigned long loadaddr; + + /* Read the rest of the Elf header... */ + if ((*(file->fs->read))(file, size, &e->e_version) < size) { +@@ -1321,13 +1399,7 @@ load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo) + loadaddr = loadinfo->load_loc; + } + +- /* On some systems, loadaddr may already be claimed, so try some +- * other nearby addresses before giving up. +- */ +- for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) { +- loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0); +- if (loadinfo->base != (void *)-1) break; +- } ++ loadinfo->base = prom_claim_chunk((void *)loadaddr, loadinfo->memsize, 0); + if (loadinfo->base == (void *)-1) { + prom_printf("Claim error, can't allocate kernel memory\n"); + goto bail; +@@ -1377,7 +1449,7 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo) + Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr); + Elf64_Phdr *p, *ph; + int size = sizeof(Elf64_Ehdr) - sizeof(Elf_Ident); +- unsigned long addr, loadaddr; ++ unsigned long loadaddr; + + /* Read the rest of the Elf header... */ + if ((*(file->fs->read))(file, size, &e->e_version) < size) { +@@ -1465,13 +1537,7 @@ load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo) + loadaddr = e->e_entry; + } + +- /* On some systems, loadaddr may already be claimed, so try some +- * other nearby addresses before giving up. +- */ +- for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) { +- loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0); +- if (loadinfo->base != (void *)-1) break; +- } ++ loadinfo->base = prom_claim_chunk((void *)loadaddr, loadinfo->memsize, 0); + if (loadinfo->base == (void *)-1) { + prom_printf("Claim error, can't allocate kernel memory\n"); + goto bail; +@@ -1625,6 +1691,7 @@ int + yaboot_main(void) + { + char *ptype; ++ char *endp; + int conf_given = 0; + char conf_path[1024]; + +@@ -1635,6 +1702,11 @@ yaboot_main(void) + DEBUG_F("/chosen/bootargs = %s\n", bootargs); + prom_get_chosen("bootpath", bootdevice, BOOTDEVSZ); + DEBUG_F("/chosen/bootpath = %s\n", bootdevice); ++ if (prom_get_options("ibm,client-architecture-support-reboot",fw_nbr_reboots, FW_NBR_REBOOTSZ) == -1 ) ++ prom_get_options("ibm,fw-nbr-reboots",fw_nbr_reboots, FW_NBR_REBOOTSZ); ++ fw_reboot_cnt = simple_strtol(fw_nbr_reboots,&endp,10); ++ if (fw_reboot_cnt > 0L) ++ prom_get_options("boot-last-label", bootlastlabel, BOOTLASTSZ); + + /* If conf= specified on command line, it overrides + Usage: conf=device:partition,/path/to/conffile +@@ -1678,11 +1750,13 @@ yaboot_main(void) + prom_printf("%s: Unable to parse\n", bootdevice); + return -1; + } ++ if (_machine == _MACH_bplan && !conf_given) ++ boot.part++; + DEBUG_F("After parse_device_path: dev=%s, part=%d, file=%s\n", + boot.dev, boot.part, boot.file); + + if (!conf_given) { +- if (_machine == _MACH_chrp) ++ if (_machine == _MACH_chrp || _machine == _MACH_bplan) + boot.file = "/etc/"; + else if (strlen(boot.file)) { + if (!strncmp(boot.file, "\\\\", 2)) diff --git a/yaboot-1.3.14-ipv6.patch b/yaboot-1.3.14-ipv6.patch new file mode 100644 index 0000000..57245e6 --- /dev/null +++ b/yaboot-1.3.14-ipv6.patch @@ -0,0 +1,129 @@ +diff -up yaboot-1.3.14/include/file.h.ipv6 yaboot-1.3.14/include/file.h +--- yaboot-1.3.14/include/file.h.ipv6 2010-02-12 07:57:43.000000000 +0100 ++++ yaboot-1.3.14/include/file.h 2010-02-12 07:57:43.000000000 +0100 +@@ -46,6 +46,11 @@ struct boot_fspec_t { + char* bootp_retries; /* Bootp retries */ + char* tftp_retries; /* TFTP retries */ + char* addl_params; /* copy all additional parameters */ ++ ++ /* Following fields are used only in ipv6 format */ ++ int is_ipv6; /* is ipv6 specified ? */ ++ char* dhcpv6; /* dhcpv6 string */ ++ char* blksize; /* blksize string */ + }; + + struct boot_file_t { +diff -up yaboot-1.3.14/include/prom.h.ipv6 yaboot-1.3.14/include/prom.h +--- yaboot-1.3.14/include/prom.h.ipv6 2010-02-12 07:57:42.000000000 +0100 ++++ yaboot-1.3.14/include/prom.h 2010-02-12 08:01:12.000000000 +0100 +@@ -40,6 +40,7 @@ typedef void *phandle; + #define PROM_CLAIM_MAX_ADDR 0x8000000 + #define BOOTLASTSZ 1024 + #define FW_NBR_REBOOTSZ 4 ++#define TOK_IPV6 "ipv6" + + struct prom_args; + typedef int (*prom_entry)(struct prom_args *); +diff -up yaboot-1.3.14/second/file.c.ipv6 yaboot-1.3.14/second/file.c +--- yaboot-1.3.14/second/file.c.ipv6 2010-02-12 07:57:43.000000000 +0100 ++++ yaboot-1.3.14/second/file.c 2010-02-12 07:57:43.000000000 +0100 +@@ -193,6 +193,50 @@ extract_netinfo_args(struct boot_fspec_t + } + + /* ++ * Extract all the ipv6 arguments from the bootpath provided and fill result ++ * Syntax: ipv6,[dhcpv6[=diaddr,]]ciaddr=c_iaddr,giaddr=g_iaddr,siaddr=s_iaddr, ++ * filename=file_name,tftp-retries=tftp_retries,blksize=block_size ++ * Returns 1 on success, 0 on failure. ++ */ ++static int ++extract_ipv6_args(char *imagepath, struct boot_fspec_t *result) ++{ ++ char *str, *tmp; ++ int total_len; ++ ++ result->is_ipv6 = 1; ++ ++ /* Just allocate the max required size */ ++ total_len = strlen(imagepath) + 1; ++ str = malloc(total_len); ++ if (!str) ++ return 0; ++ ++ if ((tmp = strstr(imagepath, "dhcpv6=")) != NULL) ++ result->dhcpv6 = scopy(&str, &tmp); ++ ++ if ((tmp = strstr(imagepath, "ciaddr=")) != NULL) ++ result->ciaddr = scopy(&str, &tmp); ++ ++ if ((tmp = strstr(imagepath, "giaddr=")) != NULL) ++ result->giaddr = scopy(&str, &tmp); ++ ++ if ((tmp = strstr(imagepath, "siaddr=")) != NULL) ++ result->siaddr = scopy(&str, &tmp); ++ ++ if ((tmp = strstr(imagepath, "filename=")) != NULL) ++ result->file = scopy(&str, &tmp); ++ ++ if ((tmp = strstr(imagepath, "tftp-retries=")) != NULL) ++ result->tftp_retries = scopy(&str, &tmp); ++ ++ if ((tmp = strstr(imagepath, "blksize=")) != NULL) ++ result->blksize = scopy(&str, &tmp); ++ ++ return 1; ++} ++ ++/* + * Extract all the arguments provided in the imagepath and fill it in result. + * Returns 1 on success, 0 on failure. + */ +@@ -206,9 +250,14 @@ extract_netboot_args(char *imagepath, st + if (!imagepath) + return 1; + +- ret = extract_ipv4_args(imagepath, result); ++ if (strstr(imagepath, TOK_IPV6)) ++ ret = extract_ipv6_args(imagepath, result); ++ else ++ ret = extract_ipv4_args(imagepath, result); ++ + ret |= extract_netinfo_args(result); + ++ DEBUG_F("ipv6 = <%d>\n", result->is_ipv6); + DEBUG_F("siaddr = <%s>\n", result->siaddr); + DEBUG_F("file = <%s>\n", result->file); + DEBUG_F("ciaddr = <%s>\n", result->ciaddr); +@@ -216,6 +265,8 @@ extract_netboot_args(char *imagepath, st + DEBUG_F("bootp_retries = <%s>\n", result->bootp_retries); + DEBUG_F("tftp_retries = <%s>\n", result->tftp_retries); + DEBUG_F("addl_params = <%s>\n", result->addl_params); ++ DEBUG_F("dhcpv6 = <%s>\n", result->dhcpv6); ++ DEBUG_F("blksize = <%s>\n", result->blksize); + + return ret; + } +diff -up yaboot-1.3.14/second/fs_of.c.ipv6 yaboot-1.3.14/second/fs_of.c +--- yaboot-1.3.14/second/fs_of.c.ipv6 2010-02-12 07:57:43.000000000 +0100 ++++ yaboot-1.3.14/second/fs_of.c 2010-02-12 07:57:43.000000000 +0100 +@@ -148,14 +148,18 @@ of_net_open(struct boot_file_t* file, + *p = '\\'; + } + +- DEBUG_F("siaddr <%s>; filename <%s>; ciaddr <%s>; giaddr <%s>;\n", +- fspec->siaddr, filename, fspec->ciaddr, fspec->giaddr); ++ DEBUG_F("siaddr <%s>; filename <%s>; ciaddr <%s>; giaddr <%s>; ipv6 <%d>\n", ++ fspec->siaddr, filename, fspec->ciaddr, fspec->giaddr, fspec->is_ipv6); + strncpy(buffer, fspec->dev, 768); ++ if (fspec->is_ipv6) ++ strcat(buffer, TOK_IPV6 ","); + /* If we didn't get a ':' include one */ + if (fspec->dev[strlen(fspec->dev)-1] != ':') + strcat(buffer, ":"); + strcat(buffer, fspec->siaddr); + strcat(buffer, ","); ++ if (fspec->is_ipv6 && (strstr(filename, "filename=") == NULL)) ++ strcat(buffer, "filename="); + strcat(buffer, filename); + strcat(buffer, ","); + strcat(buffer, fspec->ciaddr); diff --git a/yaboot-1.3.14-iscsi.patch b/yaboot-1.3.14-iscsi.patch new file mode 100644 index 0000000..816bae7 --- /dev/null +++ b/yaboot-1.3.14-iscsi.patch @@ -0,0 +1,55 @@ +Index: b/second/file.c +=================================================================== +--- a/second/file.c ++++ b/second/file.c +@@ -671,6 +671,9 @@ + case FILE_DEVICE_BLOCK: + DEBUG_F("device is a block device\n"); + return file_block_open(file, spec, spec->part); ++ case FILE_DEVICE_ISCSI: ++ DEBUG_F("device is a iSCSI device\n"); ++ return file_block_open(file, spec, spec->part); + case FILE_DEVICE_NET: + DEBUG_F("device is a network device\n"); + return file_net_open(file, spec); +Index: b/second/partition.c +=================================================================== +--- a/second/partition.c ++++ b/second/partition.c +@@ -400,7 +400,8 @@ + struct partition_t* found; + char *type = NULL; + +- if (prom_get_devtype(device) != FILE_DEVICE_BLOCK) ++ int device_kind = prom_get_devtype(device); ++ if (device_kind != FILE_DEVICE_BLOCK && device_kind != FILE_DEVICE_ISCSI) + return NULL; + + parts = partitions_lookup(device); +Index: b/second/prom.c +=================================================================== +--- a/second/prom.c ++++ b/second/prom.c +@@ -196,7 +196,7 @@ + char tmp[64]; + + if (strstr(device, TOK_ISCSI)) +- device = strcpy(tmp, "/vdevice/gscsi/disk"); ++ return FILE_DEVICE_ISCSI; + + /* Find OF device phandle */ + dev = prom_finddevice(device); +Index: b/second/fs_ext2.c +=================================================================== +--- a/second/fs_ext2.c ++++ b/second/fs_ext2.c +@@ -139,7 +139,8 @@ + DEBUG_LEAVE(FILE_ERR_FSBUSY); + return FILE_ERR_FSBUSY; + } +- if (file->device_kind != FILE_DEVICE_BLOCK) { ++ if (file->device_kind != FILE_DEVICE_BLOCK ++ && file->device_kind != FILE_DEVICE_ISCSI) { + DEBUG_LEAVE(FILE_ERR_BADDEV); + return FILE_ERR_BADDEV; + } diff --git a/yaboot-1.3.14-memory_management.patch b/yaboot-1.3.14-memory_management.patch new file mode 100644 index 0000000..da84581 --- /dev/null +++ b/yaboot-1.3.14-memory_management.patch @@ -0,0 +1,192 @@ +diff -ur yaboot-1.3.14.orig/include/fs.h yaboot-1.3.14/include/fs.h +--- yaboot-1.3.14.orig/include/fs.h 2010-08-03 15:28:29.886806113 -0500 ++++ yaboot-1.3.14/include/fs.h 2010-08-03 15:47:40.274304966 -0500 +@@ -44,6 +44,8 @@ + unsigned int newpos); + + int (*close)( struct boot_file_t* file); ++ ++ unsigned int (*ino_size)(struct boot_file_t *file); + }; + + extern const struct fs_t *fs_of; +diff -ur yaboot-1.3.14.orig/include/prom.h yaboot-1.3.14/include/prom.h +--- yaboot-1.3.14.orig/include/prom.h 2010-08-03 15:28:29.916805885 -0500 ++++ yaboot-1.3.14/include/prom.h 2010-08-03 15:47:40.274304966 -0500 +@@ -37,7 +37,7 @@ + #define PROM_INVALID_HANDLE ((prom_handle)-1UL) + #define BOOTDEVSZ (2048) /* iscsi args can be in excess of 1040 bytes */ + #define TOK_ISCSI "iscsi" +-#define PROM_CLAIM_MAX_ADDR 0x8000000 ++#define PROM_CLAIM_MAX_ADDR 0x10000000 + #define BOOTLASTSZ 1024 + #define FW_NBR_REBOOTSZ 4 + #define TOK_IPV6 "ipv6" +@@ -89,6 +89,7 @@ + /* memory */ + + void *prom_claim_chunk(void *virt, unsigned int size, unsigned int align); ++void *prom_claim_chunk_top(unsigned int size, unsigned int align); + void *prom_claim (void *virt, unsigned int size, unsigned int align); + void prom_release(void *virt, unsigned int size); + void prom_map (void *phys, void *virt, int size); +diff -ur yaboot-1.3.14.orig/second/fs_ext2.c yaboot-1.3.14/second/fs_ext2.c +--- yaboot-1.3.14.orig/second/fs_ext2.c 2010-08-03 15:28:29.916805885 -0500 ++++ yaboot-1.3.14/second/fs_ext2.c 2010-08-03 15:47:40.274304966 -0500 +@@ -54,6 +54,7 @@ + static int ext2_seek( struct boot_file_t* file, + unsigned int newpos); + static int ext2_close( struct boot_file_t* file); ++static unsigned int ext2_ino_size(struct boot_file_t *file); + + struct fs_t ext2_filesystem = + { +@@ -61,7 +62,8 @@ + ext2_open, + ext2_read, + ext2_seek, +- ext2_close ++ ext2_close, ++ ext2_ino_size, + }; + + /* IO manager structure for the ext2 library */ +@@ -565,6 +567,16 @@ + return 0; + } + ++static unsigned int ext2_ino_size(struct boot_file_t *file) ++{ ++ struct ext2_inode ei; ++ ++ if (ext2fs_read_inode(fs, file->inode, &ei)) ++ return 0; ++ ++ return ei.i_size; ++} ++ + static errcode_t linux_open (const char *name, int flags, io_channel * channel) + { + io_channel io; +diff -ur yaboot-1.3.14.orig/second/fs_of.c yaboot-1.3.14/second/fs_of.c +--- yaboot-1.3.14.orig/second/fs_of.c 2010-08-03 15:28:29.896804336 -0500 ++++ yaboot-1.3.14/second/fs_of.c 2010-08-03 15:47:40.274304966 -0500 +@@ -44,7 +44,6 @@ + #include "errors.h" + #include "debug.h" + +-#define LOAD_BUFFER_POS 0x00000000 + #define LOAD_BUFFER_SIZE 0x02000000 + + static int of_open(struct boot_file_t* file, +@@ -58,6 +57,7 @@ + struct partition_t* part, struct boot_fspec_t* fspec); + static int of_net_read(struct boot_file_t* file, unsigned int size, void* buffer); + static int of_net_seek(struct boot_file_t* file, unsigned int newpos); ++static unsigned int of_net_ino_size(struct boot_file_t* file); + + + struct fs_t of_filesystem = +@@ -75,7 +75,8 @@ + of_net_open, + of_net_read, + of_net_seek, +- of_close ++ of_close, ++ of_net_ino_size, + }; + + static int +@@ -206,8 +207,7 @@ + } + + +- file->buffer = prom_claim_chunk((void *)LOAD_BUFFER_POS, +- LOAD_BUFFER_SIZE, 0); ++ file->buffer = prom_claim_chunk_top(LOAD_BUFFER_SIZE, 0); + if (file->buffer == (void *)-1) { + prom_printf("Can't claim memory for TFTP download\n"); + prom_close(file->of_device); +@@ -284,6 +284,12 @@ + return 0; + } + ++static unsigned int ++of_net_ino_size(struct boot_file_t* file) ++{ ++ return file->len; ++} ++ + /* + * Local variables: + * c-file-style: "k&r" +diff -ur yaboot-1.3.14.orig/second/prom.c yaboot-1.3.14/second/prom.c +--- yaboot-1.3.14.orig/second/prom.c 2010-08-03 15:28:29.916805885 -0500 ++++ yaboot-1.3.14/second/prom.c 2010-08-03 15:48:08.934304926 -0500 +@@ -548,6 +548,23 @@ + return((void*)-1); + } + ++/* Start from top of memory and work down to get the needed space */ ++void * ++prom_claim_chunk_top(unsigned int size, unsigned int align) ++{ ++ void *found, *addr; ++ for(addr=(void*)PROM_CLAIM_MAX_ADDR; addr >= (void *)size; ++ addr-=(0x100000/sizeof(addr))) { ++ found = call_prom("claim", 3, 1, addr, size, 0); ++ if (found != (void *)-1) { ++ prom_printf("claim of 0x%x at 0x%x returned 0x%x\n", size, (int)addr, (int)found); ++ return(found); ++ } ++ } ++ prom_printf("ERROR: claim of 0x%x in range 0x0-0x%x failed\n", size, PROM_CLAIM_MAX_ADDR); ++ return((void*)-1); ++} ++ + void * + prom_claim (void *virt, unsigned int size, unsigned int align) + { +diff -ur yaboot-1.3.14.orig/second/yaboot.c yaboot-1.3.14/second/yaboot.c +--- yaboot-1.3.14.orig/second/yaboot.c 2010-08-03 15:28:29.906805706 -0500 ++++ yaboot-1.3.14/second/yaboot.c 2010-08-03 15:47:40.274304966 -0500 +@@ -1211,25 +1211,33 @@ + } + else { + #define INITRD_CHUNKSIZE 0x100000 +- initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 0); ++ unsigned int len = INITRD_CHUNKSIZE; ++ ++ /* We add a bit to the actual size so the loop below doesn't think ++ * there is more to load. ++ */ ++ if (file.fs->ino_size && file.fs->ino_size(&file) > 0) ++ len = file.fs->ino_size(&file) + 0x1000; ++ ++ initrd_base = prom_claim_chunk(loadinfo.base+loadinfo.memsize, len, 0); + if (initrd_base == (void *)-1) { + prom_printf("Claim failed for initrd memory\n"); + initrd_base = 0; + } else { +- initrd_size = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_base); ++ initrd_size = file.fs->read(&file, len, initrd_base); + if (initrd_size == 0) + initrd_base = 0; + initrd_read = initrd_size; + initrd_more = initrd_base; +- while (initrd_read == INITRD_CHUNKSIZE ) { /* need to read more? */ +- initrd_want = (void *)((unsigned long)initrd_more+INITRD_CHUNKSIZE); +- initrd_more = prom_claim(initrd_want, INITRD_CHUNKSIZE, 0); ++ while (initrd_read == len ) { /* need to read more? */ ++ initrd_want = (void *)((unsigned long)initrd_more+len); ++ initrd_more = prom_claim(initrd_want, len, 0); + if (initrd_more != initrd_want) { + prom_printf("Claim failed for initrd memory at %p rc=%p\n",initrd_want,initrd_more); + prom_pause(); + break; + } +- initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more); ++ initrd_read = file.fs->read(&file, len, initrd_more); + DEBUG_F(" block at %p rc=%lu\n",initrd_more,initrd_read); + initrd_size += initrd_read; + initrd_end = initrd_more+INITRD_CHUNKSIZE; diff --git a/yaboot-1.3.14-move_kernel.patch b/yaboot-1.3.14-move_kernel.patch new file mode 100644 index 0000000..8142646 --- /dev/null +++ b/yaboot-1.3.14-move_kernel.patch @@ -0,0 +1,118 @@ +diff --git a/Makefile b/Makefile +index 8f2b1c4..3603c7d 100644 +--- a/Makefile ++++ b/Makefile +@@ -121,6 +121,9 @@ mkofboot: + false; \ + fi + ++%.i: %.c ++ $(CC) $(YBCFLAGS) -E -o $@ $< ++ + %.o: %.c + $(CC) $(YBCFLAGS) -c -o $@ $< + +diff --git a/include/file.h b/include/file.h +index b2d9c63..9990f4b 100644 +--- a/include/file.h ++++ b/include/file.h +@@ -68,6 +68,7 @@ struct boot_file_t { + ino_t inode; + __u64 pos; + unsigned char* buffer; ++ __u64 buffer_sz; + __u64 len; + // unsigned int dev_blk_size; + // unsigned int part_start; +diff --git a/second/fs_of.c b/second/fs_of.c +index 1f48f4f..d2e7434 100644 +--- a/second/fs_of.c ++++ b/second/fs_of.c +@@ -214,6 +214,7 @@ of_net_open(struct boot_file_t* file, + DEBUG_LEAVE(FILE_IOERR); + return FILE_IOERR; + } ++ file->buffer_sz = LOAD_BUFFER_SIZE; + memset(file->buffer, 0, LOAD_BUFFER_SIZE); + + DEBUG_F("TFP...\n"); +diff --git a/second/yaboot.c b/second/yaboot.c +index 0ccfed5..1241eec 100644 +--- a/second/yaboot.c ++++ b/second/yaboot.c +@@ -1052,6 +1052,7 @@ yaboot_text_ui(void) + static struct boot_param_t params; + void *initrd_base; + unsigned long initrd_size; ++ unsigned long initrd_end; + void *sysmap_base; + unsigned long sysmap_size; + kernel_entry_t kernel_entry; +@@ -1227,8 +1228,67 @@ yaboot_text_ui(void) + initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more); + DEBUG_F(" block at %p rc=%lu\n",initrd_more,initrd_read); + initrd_size += initrd_read; ++ initrd_end = initrd_more+INITRD_CHUNKSIZE; + } + } ++ /* If we netbooted and got this far, we may have filled the ++ * RMA. We're about the free the TFTP load buffer to we ++ * can "shuffle" things around so that the booted kernel ++ * has some memory to run with */ ++ if (!is_elf64(&loadinfo)) { ++ DEBUG_F("Not running a 64-kernel\n"); ++ /* Is this check enough? */ ++ } else if (loadinfo.base == file.buffer + file.buffer_sz) { ++ DEBUG_F("file->buffer %lx -> %lx (%lx)\n", ++ (unsigned long)(file.buffer), ++ (unsigned long)(file.buffer+file.buffer_sz), ++ (unsigned long)(file.buffer_sz)); ++ DEBUG_F("vmlinux %lx -> %lx (%lx)\n", ++ (unsigned long)(loadinfo.base), ++ (unsigned long)(loadinfo.base+loadinfo.memsize), ++ (unsigned long)(loadinfo.memsize)); ++ DEBUG_F("initrd %lx -> %lx (%lx)\n", ++ (unsigned long)(initrd_base), ++ (unsigned long)(initrd_base+initrd_size), ++ (unsigned long)(initrd_size)); ++ ++ /* Check to see if we're near the top of the RMA */ ++ /* Cheat and assume the RMA == 128Mb */ ++ if (initrd_end > 0x7000000) { ++ unsigned long new_initrd_end, free_len; ++ unsigned long initrd_claim_len = initrd_end - (unsigned long)initrd_base; ++ ++ memmove(file.buffer, loadinfo.base, ++ loadinfo.memsize+initrd_size); ++ loadinfo.base = file.buffer; ++ initrd_base = loadinfo.base+loadinfo.memsize; ++ ++ new_initrd_end = (unsigned long)initrd_base+initrd_claim_len; ++ free_len = initrd_end - (unsigned long)new_initrd_end; ++ file.buffer = NULL; ++ file.buffer_sz = 0; ++ memset((void*)new_initrd_end, 0x0, free_len); ++ prom_release((void*)new_initrd_end, free_len); ++ ++ DEBUG_F("Releaseing from 0x%08lx -> 0x%08lx\n", ++ new_initrd_end, free_len); ++ ++ DEBUG_F("file->buffer %lx -> %lx (%lx)\n", ++ (unsigned long)(file.buffer), ++ (unsigned long)(file.buffer+file.buffer_sz), ++ (unsigned long)(file.buffer_sz)); ++ DEBUG_F("vmlinux %lx -> %lx (%lx)\n", ++ (unsigned long)(loadinfo.base), ++ (unsigned long)(loadinfo.base+loadinfo.memsize), ++ (unsigned long)(loadinfo.memsize)); ++ DEBUG_F("initrd %lx -> %lx (%lx)\n", ++ (unsigned long)(initrd_base), ++ (unsigned long)(initrd_base+initrd_size), ++ (unsigned long)(initrd_size)); ++ } else { ++ DEBUG_F("Looks like we do not need to move the kernel\n"); ++ } ++ } + file.fs->close(&file); + memset(&file, 0, sizeof(file)); + } diff --git a/yaboot-1.3.14-netinfo.patch b/yaboot-1.3.14-netinfo.patch new file mode 100644 index 0000000..b366956 --- /dev/null +++ b/yaboot-1.3.14-netinfo.patch @@ -0,0 +1,66 @@ +extract_netinfo_args() should be a void function. + +If there is no "netinfo" packet, extract_netinfo_args() will fail and cause +parse_device_path() to abort. This basically meant that yaboot will fail to +load any kernel/initrd under those circumstances. + +This fix changes extract_netinfo_args() to be a void function. + +Signed-off-by: Tony Breeds +--- +I'll talk to FW about /why/ there is no netinfo data, but even if that is a FW bug we need to work around it. + + second/file.c | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +--- yaboot-1.3.14.orig/second/file.c 2010-03-06 09:23:12.174204856 +0800 ++++ yaboot-1.3.14/second/file.c 2010-03-06 11:59:04.045205260 +0800 +@@ -260,10 +260,8 @@ extract_vendor_options(struct bootp_pack + /* + * Check netinfo for ipv4 parameters and add them to the fspec iff the + * fspec has no existing value. +- * +- * Returns 1 on success, 0 on failure. + */ +-static int ++static void + extract_netinfo_args(struct boot_fspec_t *result) + { + struct bootp_packet *packet; +@@ -271,7 +269,7 @@ extract_netinfo_args(struct boot_fspec_t + /* Check to see if we can get the [scyg]iaddr fields from netinfo */ + packet = prom_get_netinfo(); + if (packet == NULL) +- return 0; ++ return; + + DEBUG_F("We have a boot packet\n"); + DEBUG_F(" siaddr = <%x>\n", packet->siaddr); +@@ -303,8 +301,6 @@ extract_netinfo_args(struct boot_fspec_t + result->giaddr = ipv4_to_str(packet->siaddr); + DEBUG_F("Forcing giaddr to siaddr <%s>\n", result->giaddr); + } +- +- return 1; + } + + /* +@@ -370,7 +366,7 @@ extract_netboot_args(char *imagepath, st + else + ret = extract_ipv4_args(imagepath, result); + +- ret |= extract_netinfo_args(result); ++ extract_netinfo_args(result); + + DEBUG_F("ipv6 = <%d>\n", result->is_ipv6); + DEBUG_F("siaddr = <%s>\n", result->siaddr); +@@ -526,8 +522,7 @@ parse_device_path(char *imagepath, char + return 0; + } else { + /* If we didn't get a ':' then look only in netinfo */ +- if (extract_netinfo_args(result) == 0) +- return 0; ++ extract_netinfo_args(result); + result->file = strdup(ipath); + } + diff --git a/yaboot-1.3.14-no-birecs.patch b/yaboot-1.3.14-no-birecs.patch new file mode 100644 index 0000000..96748c7 --- /dev/null +++ b/yaboot-1.3.14-no-birecs.patch @@ -0,0 +1,11 @@ +--- yaboot-1.3.14/second/yaboot.c~ 2009-06-07 08:57:58.000000000 +0100 ++++ yaboot-1.3.14/second/yaboot.c 2009-06-07 09:02:03.000000000 +0100 +@@ -1243,7 +1243,7 @@ yaboot_text_ui(void) + flush_icache_range ((long)loadinfo.base, (long)loadinfo.base+loadinfo.memsize); + DEBUG_F(" done\n"); + +- if (flat_vmlinux) { ++ if (0 && flat_vmlinux) { + /* + * Fill new boot infos (only if booting a vmlinux). + * diff --git a/yaboot-1.3.14-prom_getchars.patch b/yaboot-1.3.14-prom_getchars.patch new file mode 100644 index 0000000..bf4e048 --- /dev/null +++ b/yaboot-1.3.14-prom_getchars.patch @@ -0,0 +1,95 @@ +Date: Sun, 11 Apr 2010 14:05:59 +1000 +From: Anton Blanchard +Subject: prom_getchar eats characters + +This bug has been annoying me for a long time. If you copy and paste a +string into the yaboot prompt, or even type too fast, characters get +dropped. + +It turns out we were asking OF for 4 characters, but only using the first one. +There is strange logic to look for \e[, and then oring the third character with +0x100. I haven't been able to find anyone that knows why that was there in the +first place, so just remove it and fix this bug once and for all. + +Automated test infrastructures the world over will thank us for fixing this +bug! + +Signed-off-by: Anton Blanchard +Signed-off-by: Tony Breeds + +--- +diff -purN yaboot-1.3.14.orig/include/prom.h yaboot-1.3.14/include/prom.h +--- yaboot-1.3.14.orig/include/prom.h 2010-05-13 22:32:41.363286396 -0500 ++++ yaboot-1.3.14/include/prom.h 2010-05-15 22:45:20.057035750 -0500 +@@ -84,7 +84,6 @@ void prom_printf (char *fmt, ...); + #endif + + void prom_perror (int error, char *filename); +-void prom_readline (char *prompt, char *line, int len); + int prom_set_color(prom_handle device, int color, int r, int g, int b); + + /* memory */ +diff -purN yaboot-1.3.14.orig/second/prom.c yaboot-1.3.14/second/prom.c +--- yaboot-1.3.14.orig/second/prom.c 2010-05-13 22:32:41.383286111 -0500 ++++ yaboot-1.3.14/second/prom.c 2010-05-15 22:45:43.615473125 -0500 +@@ -389,14 +389,12 @@ prom_readblocks (prom_handle dev, int bl + int + prom_getchar () + { +- char c[4]; ++ char c; + int a; + +- while ((a = (int)call_prom ("read", 3, 1, prom_stdin, c, 4)) <= 0) +- ; +- if (a == 3 && c[0] == '\e' && c[1] == '[') +- return 0x100 | c[2]; +- return c[0]; ++ while ((a = (int)call_prom ("read", 3, 1, prom_stdin, &c, 1)) <= 0) ++ continue; ++ return c; + } + + int +@@ -500,41 +498,6 @@ prom_perror (int error, char *filename) + prom_printf("%s: Unknown error\n", filename); + } + +-void +-prom_readline (char *prompt, char *buf, int len) +-{ +- int i = 0; +- int c; +- +- if (prompt) +- prom_puts (prom_stdout, prompt); +- +- while (i < len-1 && (c = prom_getchar ()) != '\r') +- { +- if (c >= 0x100) +- continue; +- if (c == 8) +- { +- if (i > 0) +- { +- prom_puts (prom_stdout, "\b \b"); +- i--; +- } +- else +- prom_putchar ('\a'); +- } +- else if (isprint (c)) +- { +- prom_putchar (c); +- buf[i++] = c; +- } +- else +- prom_putchar ('\a'); +- } +- prom_putchar ('\n'); +- buf[i] = 0; +-} +- + #ifdef CONFIG_SET_COLORMAP + int prom_set_color(prom_handle device, int color, int r, int g, int b) + { diff --git a/yaboot-1.3.14-returns.patch b/yaboot-1.3.14-returns.patch new file mode 100644 index 0000000..b3d66da --- /dev/null +++ b/yaboot-1.3.14-returns.patch @@ -0,0 +1,11 @@ +--- yaboot-1.3.14/ybin/ybin.orig 2009-08-07 11:08:04.000000000 +1000 ++++ yaboot-1.3.14/ybin/ybin 2009-08-07 11:08:09.000000000 +1000 +@@ -1164,6 +1164,8 @@ + fi + sync ; sync + [ "$VERBOSE" = 1 ] && echo "$PRG: Installation successful" ++ ++ return 0 + } + + ## make sure the first stage ofboot generator is compatible. diff --git a/yaboot-1.3.3-man.patch b/yaboot-1.3.3-man.patch new file mode 100644 index 0000000..24557e9 --- /dev/null +++ b/yaboot-1.3.3-man.patch @@ -0,0 +1,132 @@ +diff -urN -X CVS man/mkofboot.8 man.deb/mkofboot.8 +--- man/mkofboot.8 Thu May 24 04:32:54 2001 ++++ man.deb/mkofboot.8 Tue Sep 25 05:38:42 2001 +@@ -94,7 +94,7 @@ + .TP + .BR \-i ,\ \-\-install\ \fIboot-file + Use \fIboot-file\fR as the primary boot loader executable, instead of +-the default\fI/usr/local/lib/yaboot/yaboot\fR(8). ++the default\fI/usr/lib/yaboot/yaboot\fR(8). + .TP + .BR \-C ,\ \-\-config\ \fIconfig-file + Use \fIconfig-file\fR as the \fBmkofboot\fR/\fByaboot\fR(8) configuration +@@ -200,8 +200,8 @@ + Print out the version number and exit. + .SH FILES + .nf +-/usr/local/lib/yaboot/yaboot \- boot loader executable +-/usr/local/lib/yaboot/ofboot \- OpenFirmware boot script ++/usr/lib/yaboot/yaboot \- boot loader executable ++/usr/lib/yaboot/ofboot \- OpenFirmware boot script + /etc/yaboot.conf \- boot loader/mkofboot configuration file + .fi + .SH ENVIRONMENT +@@ -218,7 +218,7 @@ + program otherwise \fBmkofboot\fR will be vulnerable to race conditions. + The Debian mktemp is derived from OpenBSD and thus should be secure. + +-\fI/usr/local/lib/yaboot/ofboot\fR now contains code executed by /bin/sh (by ++\fI/usr/lib/yaboot/ofboot\fR now contains code executed by /bin/sh (by + \fBmkofboot\fR) it is thus critical that it not be writable by anyone + but root. It is also critical that \fI/etc/yaboot.conf\fR not be + writable by anyone but root since a different \fIofboot\fR script could be +diff -urN -X CVS man/yaboot.conf.5 man.deb/yaboot.conf.5 +--- man/yaboot.conf.5 Tue Sep 25 05:20:03 2001 ++++ man.deb/yaboot.conf.5 Tue Sep 25 05:38:42 2001 +@@ -136,7 +136,7 @@ + boot=/dev/hda2 + device=hd: + partition=3 +- magicboot=/usr/local/lib/yaboot/ofboot ++ magicboot=/usr/lib/yaboot/ofboot + timeout=50 + root=/dev/hda3 + read-only +@@ -228,7 +228,7 @@ + magicboot script will be executed by OF automatically at boot (instead + of the \fBinstall\fR file.) See man \fBbootstrap\fR(8) for more + information on this. As of ybin 0.22 you should set this to +-/usr/local/lib/yaboot/ofboot which is a autoconfiguring first stage ++/usr/lib/yaboot/ofboot which is a autoconfiguring first stage + loader for yaboot. It is capable of presenting a dual boot menu for + GNU/Linux, MacOS and MacOSX. If dual booting is not required or + configured it will simply load yaboot directly. You must specify this +@@ -301,7 +301,7 @@ + When you define this option you will be presented with a simple menu at + bootup allowing you to hit L to boot GNU/Linux or B to boot BSD (along + with other choices if configured). This will only work if you are +-using the new \fI/usr/local/lib/yaboot/ofboot\fR script. When this is ++using the new \fI/usr/lib/yaboot/ofboot\fR script. When this is + set to a unix device node (ie \fI/dev/hda11\fR) then ybin will use the + \fBofpath\fR(8) utility to determine the OpenFirmware device path. + .TP +@@ -310,7 +310,7 @@ + partition. When you define this option you will be presented with a + simple menu at bootup allowing you to hit L to boot GNU/Linux or M to + boot MacOS (along with other choices if configured). This will only +-work if you are using the new \fI/usr/local/lib/yaboot/ofboot\fR ++work if you are using the new \fI/usr/lib/yaboot/ofboot\fR + script. When this is set to a unix device node (ie \fI/dev/hda11\fR) + then ybin will use the \fBofpath\fR(8) utility to determine the + OpenFirmware device path. +@@ -320,7 +320,7 @@ + When you define this option you will be presented with a simple menu + at bootup allowing you to hit L to boot GNU/Linux or X to boot MacOSX + (along with other choices if configured). This will only work if you +-are using the new \fI/usr/local/lib/yaboot/ofboot\fR script. When ++are using the new \fI/usr/lib/yaboot/ofboot\fR script. When + this is set to a unix device node (ie \fI/dev/hda11\fR) then ybin will + use the \fBofpath\fR(8) utility to determine the OpenFirmware device + path. +@@ -341,7 +341,7 @@ + When you define this option you will be presented with a simple menu + at bootup allowing you to hit L to boot GNU/Linux or D to boot Darwin + (along with other choices if configured). This will only work if you +-are using the new \fI/usr/local/lib/yaboot/ofboot\fR script. When ++are using the new \fI/usr/lib/yaboot/ofboot\fR script. When + this is set to a unix device node (ie \fI/dev/hda11\fR) then ybin will + use the \fBofpath\fR(8) utility to determine the OpenFirmware device + path. +@@ -589,8 +589,8 @@ + root=/dev/hda3 + partition=3 + timeout=20 +-install=/usr/local/lib/yaboot/yaboot +-magicboot=/usr/local/lib/yaboot/ofboot ++install=/usr/lib/yaboot/yaboot ++magicboot=/usr/lib/yaboot/ofboot + fgcolor=black + bgcolor=green + default=Linux +diff -urN -X CVS man/ybin.8 man.deb/ybin.8 +--- man/ybin.8 Thu May 24 04:33:16 2001 ++++ man.deb/ybin.8 Tue Sep 25 05:38:42 2001 +@@ -109,7 +109,7 @@ + .TP + .BR \-i ,\ \-\-install\ \fIboot-file + Use \fIboot-file\fR as the primary boot loader executable, instead of +-the default \fI/usr/local/lib/yaboot/yaboot\fR. ++the default \fI/usr/lib/yaboot/yaboot\fR. + .TP + .BR \-C ,\ \-\-config\ \fIconfig-file + Use \fIconfig-file\fR as the \fBybin\fR/\fByaboot\fR(8) configuration +@@ -214,8 +214,8 @@ + Print out the version number and exit. + .SH FILES + .nf +-/usr/local/lib/yaboot/yaboot \- boot loader executable +-/usr/local/lib/yaboot/ofboot \- OpenFirmware boot script ++/usr/lib/yaboot/yaboot \- boot loader executable ++/usr/lib/yaboot/ofboot \- OpenFirmware boot script + /etc/yaboot.conf \- boot loader/ybin configuration file + .fi + .SH ENVIRONMENT +@@ -232,7 +232,7 @@ + program, otherwise \fBybin\fR will be vulnerable to race conditions. + The Debian mktemp is derived from OpenBSD and thus should be secure. + +-\fI/usr/local/lib/yaboot/ofboot\fR now contains code executed by /bin/sh (by ++\fI/usr/lib/yaboot/ofboot\fR now contains code executed by /bin/sh (by + \fBybin\fR). It is thus critical that it not be writable by anyone but + root. It is also critical that \fI/etc/yaboot.conf\fR not be writable + by anyone but root since a different \fIofboot\fR script could be diff --git a/yaboot-1.3.6-ofboot.patch b/yaboot-1.3.6-ofboot.patch new file mode 100644 index 0000000..cd35657 --- /dev/null +++ b/yaboot-1.3.6-ofboot.patch @@ -0,0 +1,29 @@ +--- yaboot-1.3.6/first/ofboot.orig Thu Mar 7 04:19:09 2002 ++++ yaboot-1.3.6/first/ofboot Thu Mar 7 04:21:49 2002 +@@ -102,7 +102,7 @@ + [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "$PRG: DEBUG: file1: $5\n" + [ "$COUNT" = "$OSNUM" ] && c="." + BTYA=": boot$1 \" Loading second stage bootstrap...\" .printf 100 ms load-base release-load-area \" ${4}${5}\" \$boot ;" +- MENUYA="\" Press $3 for GNU/Linux${c-,}\"(0d 0a)\" .printf" ++ MENUYA="\" Press $3 for Red Hat Linux${c-,}\"(0d 0a)\" .printf" + GETYA=" ascii $3 of \" $3 \"(0d 0a)\" .printf boot$1 endof" + shift 5 + COUNT="$(($COUNT + 1))" +@@ -315,7 +315,7 @@ + MacRISC MacRISC3 MacRISC4 + + +-PowerPC GNU/Linux First Stage Bootstrap ++Red Hat Linux First Stage Bootstrap + + + : .printf fb8-write drop ; +@@ -336,7 +336,7 @@ + $BGCOLOR to background-color + \" \"(0C)\" .printf + +-\" First Stage GNU/Linux Bootstrap\"(0d 0a)\" .printf ++\" First Stage Red Hat Linux Bootstrap\"(0d 0a)\" .printf + \" \"(0d 0a)\" .printf + $MENUOPTS + \" \"(0d 0a)\" .printf diff --git a/yaboot-1.3.6-rh.patch b/yaboot-1.3.6-rh.patch new file mode 100644 index 0000000..f701474 --- /dev/null +++ b/yaboot-1.3.6-rh.patch @@ -0,0 +1,94 @@ +--- yaboot-1.3.6/Makefile.rh Fri May 17 15:08:25 2002 ++++ yaboot-1.3.6/Makefile Fri May 17 15:09:32 2002 +@@ -178,32 +178,32 @@ + strip --remove-section=.comment --remove-section=.note util/addnote + + install: all strip +- install -d -o root -g root -m 0755 ${ROOT}/etc/ +- install -d -o root -g root -m 0755 ${ROOT}/${PREFIX}/sbin/ +- install -d -o root -g root -m 0755 ${ROOT}/${PREFIX}/lib +- install -d -o root -g root -m 0755 ${ROOT}/${PREFIX}/lib/yaboot +- install -d -o root -g root -m 0755 ${ROOT}/${PREFIX}/${MANDIR}/man5/ +- install -d -o root -g root -m 0755 ${ROOT}/${PREFIX}/${MANDIR}/man8/ +- install -o root -g root -m 0644 second/yaboot ${ROOT}/$(PREFIX)/lib/yaboot +- install -o root -g root -m 0755 util/addnote ${ROOT}/${PREFIX}/lib/yaboot/addnote +- install -o root -g root -m 0644 first/ofboot ${ROOT}/${PREFIX}/lib/yaboot/ofboot +- install -o root -g root -m 0755 ybin/ofpath ${ROOT}/${PREFIX}/sbin/ofpath +- install -o root -g root -m 0755 ybin/ybin ${ROOT}/${PREFIX}/sbin/ybin +- install -o root -g root -m 0755 ybin/yabootconfig ${ROOT}/${PREFIX}/sbin/yabootconfig ++ install -d -m 0755 ${ROOT}/etc/ ++ install -d -m 0755 ${ROOT}/${PREFIX}/sbin/ ++ install -d -m 0755 ${ROOT}/${PREFIX}/lib ++ install -d -m 0755 ${ROOT}/${PREFIX}/lib/yaboot ++ install -d -m 0755 ${ROOT}/${PREFIX}/${MANDIR}/man5/ ++ install -d -m 0755 ${ROOT}/${PREFIX}/${MANDIR}/man8/ ++ install -m 0644 second/yaboot ${ROOT}/$(PREFIX)/lib/yaboot ++ install -m 0755 util/addnote ${ROOT}/${PREFIX}/lib/yaboot/addnote ++ install -m 0644 first/ofboot ${ROOT}/${PREFIX}/lib/yaboot/ofboot ++ install -m 0755 ybin/ofpath ${ROOT}/${PREFIX}/sbin/ofpath ++ install -m 0755 ybin/ybin ${ROOT}/${PREFIX}/sbin/ybin ++ install -m 0755 ybin/yabootconfig ${ROOT}/${PREFIX}/sbin/yabootconfig + rm -f ${ROOT}/${PREFIX}/sbin/mkofboot + ln -s ybin ${ROOT}/${PREFIX}/sbin/mkofboot + @gzip -9 man/*.[58] +- install -o root -g root -m 0644 man/bootstrap.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/bootstrap.8.gz +- install -o root -g root -m 0644 man/mkofboot.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/mkofboot.8.gz +- install -o root -g root -m 0644 man/ofpath.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/ofpath.8.gz +- install -o root -g root -m 0644 man/yaboot.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/yaboot.8.gz +- install -o root -g root -m 0644 man/yabootconfig.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/yabootconfig.8.gz +- install -o root -g root -m 0644 man/ybin.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/ybin.8.gz +- install -o root -g root -m 0644 man/yaboot.conf.5.gz ${ROOT}/${PREFIX}/${MANDIR}/man5/yaboot.conf.5.gz ++ install -m 0644 man/bootstrap.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/bootstrap.8.gz ++ install -m 0644 man/mkofboot.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/mkofboot.8.gz ++ install -m 0644 man/ofpath.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/ofpath.8.gz ++ install -m 0644 man/yaboot.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/yaboot.8.gz ++ install -m 0644 man/yabootconfig.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/yabootconfig.8.gz ++ install -m 0644 man/ybin.8.gz ${ROOT}/${PREFIX}/${MANDIR}/man8/ybin.8.gz ++ install -m 0644 man/yaboot.conf.5.gz ${ROOT}/${PREFIX}/${MANDIR}/man5/yaboot.conf.5.gz + @gunzip man/*.gz + @if [ ! -e ${ROOT}/etc/yaboot.conf ] ; then \ +- echo "install -o root -g root -m 0644 etc/yaboot.conf ${ROOT}/etc/yaboot.conf"; \ +- install -o root -g root -m 0644 etc/yaboot.conf ${ROOT}/etc/yaboot.conf; \ ++ echo "install -m 0644 etc/yaboot.conf ${ROOT}/etc/yaboot.conf"; \ ++ install -m 0644 etc/yaboot.conf ${ROOT}/etc/yaboot.conf; \ + else \ + echo "/etc/yaboot.conf already exists, leaving it alone"; \ + fi +--- yaboot-1.3.6/etc/yaboot.conf.fhs Thu May 23 15:56:11 2002 ++++ yaboot-1.3.6/etc/yaboot.conf Thu May 23 15:57:29 2002 +@@ -10,7 +10,7 @@ + ## specify a partition number for this! On IBM hardware you can + ## generally comment this out. + +-device=hd: ++## device=hd: + + ## partition is the partition number where the kernel images are + ## located. The kernel images should be on your root filesystem, so +@@ -20,7 +20,7 @@ + ## option can be either set globally as shown here, or per image in + ## the image= sections + +-partition=3 ++partition=2 + + ## delay is the amount of time in seconds the dual boot menu (if one + ## is configured, by the presense of macos, macosx, etc options here) +@@ -35,13 +35,13 @@ + ## section in this config file or the value of default=). + + timeout=40 +-install=/usr/local/lib/yaboot/yaboot +-magicboot=/usr/local/lib/yaboot/ofboot ++install=/usr/lib/yaboot/yaboot ++magicboot=/usr/lib/yaboot/ofboot + + ## Change the default colors, fgcolor is the text color, bgcolor is + ## the screen background color. (default: fgcolor=white, bgcolor=black) +-#fgcolor=black +-#bgcolor=green ++fgcolor=white ++bgcolor=black + + ## Password supplied in plaintext, required for yaboot to boot, unless + ## restricted is also present (see below). Be sure to diff --git a/yaboot-relocatable-kernel.patch b/yaboot-relocatable-kernel.patch new file mode 100644 index 0000000..10e08ea --- /dev/null +++ b/yaboot-relocatable-kernel.patch @@ -0,0 +1,21 @@ +PPC64 relocatable kernels (built with CONFIG_RELOCATABLE=y) have the type of +ET_DYN. But yaboot code won't load the kernel if the ELF type is not +ET_EXEC. Attached patch adds support to yaboot to load relocatable kernels +also (ie load ET_DYN type also) + +Signed-off-by: M. Mohan Kumar +--- + second/yaboot.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- yaboot-1.3.14.orig/second/yaboot.c ++++ yaboot-1.3.14/second/yaboot.c +@@ -1606,7 +1606,7 @@ is_elf64(loadinfo_t *loadinfo) + e->e_ident[EI_MAG3] == ELFMAG3 && + e->e_ident[EI_CLASS] == ELFCLASS64 && + e->e_ident[EI_DATA] == ELFDATA2MSB && +- e->e_type == ET_EXEC && ++ (e->e_type == ET_EXEC || e->e_type == ET_DYN) && + e->e_machine == EM_PPC64); + } + diff --git a/yaboot-sha2.patch b/yaboot-sha2.patch new file mode 100644 index 0000000..b70c4ad --- /dev/null +++ b/yaboot-sha2.patch @@ -0,0 +1,1687 @@ +diff -urN --exclude '*~' yaboot/doc/yaboot-howto.sgml yaboot-1.3.14/doc/yaboot-howto.sgml +--- yaboot/doc/yaboot-howto.sgml 2008-04-15 15:34:48.000000000 +0200 ++++ yaboot-1.3.14/doc/yaboot-howto.sgml 2010-01-13 17:12:26.046808859 +0100 +@@ -487,17 +487,17 @@ + +

+ +-The password= line may either be a plaintext password or an MD5 +-hash (the same format as the Linux /etc/shadow file). To make an +-md5 hash use the following perl snippet: ++The password= line may either be a plaintext password or a ++hash (the same format as the Linux /etc/shadow file, using MD5, ++SHA-256 or SHA-512). To make a SHA-512 hash use the following perl snippet: + + +- $ perl -e 'printf("%s\n", crypt("secret", "\$1\$saltstrg"))' ++ $ perl -e 'printf("%s\n", crypt("secret", "\$6\$saltstrg"))' + + The saltstrg should be a random string, for example one generated by + + +- makepasswd --chars=8 ++ makepasswd --chars=16 + + + +diff -urN --exclude '*~' yaboot/etc/yaboot.conf yaboot-1.3.14/etc/yaboot.conf +--- yaboot/etc/yaboot.conf 2010-01-12 22:39:21.593765245 +0100 ++++ yaboot-1.3.14/etc/yaboot.conf 2010-01-13 17:09:25.957808951 +0100 +@@ -53,6 +53,10 @@ + + #password=$1$saltstrg$HnJ/gcM3oKhNbnzUPgXTD/ + ++## Password supplied as a SHA-2 hash, see above ++ ++#password=6$saltstrg$RtV84gQMyM4d9gENIlyHmaGKQXckHJBjhU4aBOpbyzcvDMSxK/dJI7e/sYJtRwl4sR9WTFCfKJLVaDY.5VdjU1 ++ + ## A password is only required to boot an image specified here if + ## parameters are specified on the command line or if the user enters + ## an image is not specified in the configuration file at all (ie. +diff -urN --exclude '*~' yaboot/include/string.h yaboot-1.3.14/include/string.h +--- yaboot/include/string.h 2008-04-15 15:34:48.000000000 +0200 ++++ yaboot-1.3.14/include/string.h 2010-01-13 14:18:51.293809297 +0100 +@@ -7,6 +7,7 @@ + extern char * ___strtok; + extern char * strcpy(char *,const char *); + extern char * strncpy(char *,const char *, size_t); ++extern char * stpncpy(char *,const char *, size_t); + extern char * strcat(char *, const char *); + extern char * strncat(char *, const char *, size_t); + extern char * strchr(const char *,int); +diff -urN --exclude '*~' yaboot/include/yaboot.h yaboot-1.3.14/include/yaboot.h +--- yaboot/include/yaboot.h 2008-04-15 15:34:48.000000000 +0200 ++++ yaboot-1.3.14/include/yaboot.h 2010-01-12 22:43:37.092766857 +0100 +@@ -59,4 +59,7 @@ + extern char *bootpath; + extern int bootpartition; + ++extern char *sha256_crypt (const char *key, const char *salt); ++extern char *sha512_crypt (const char *key, const char *salt); ++ + #endif +diff -urN --exclude '*~' yaboot/lib/stpncpy.c yaboot-1.3.14/lib/stpncpy.c +--- yaboot/lib/stpncpy.c 1970-01-01 01:00:00.000000000 +0100 ++++ yaboot-1.3.14/lib/stpncpy.c 2010-01-13 14:55:22.663809519 +0100 +@@ -0,0 +1,21 @@ ++#include "string.h" ++ ++char * ++stpncpy (char *dest, const char *src, size_t n) ++{ ++ char *res; ++ ++ res = NULL; ++ while (n != 0) { ++ *dest = *src; ++ if (*src != 0) ++ src++; ++ else if (res == NULL) ++ res = dest; ++ dest++; ++ n--; ++ } ++ if (res == NULL) ++ res = dest; ++ return res; ++} +diff -urN --exclude '*~' yaboot/Makefile yaboot-1.3.14/Makefile +--- yaboot/Makefile 2010-01-12 22:39:21.669786352 +0100 ++++ yaboot-1.3.14/Makefile 2010-01-13 14:20:28.214809232 +0100 +@@ -85,7 +85,8 @@ + OBJS = second/crt0.o second/yaboot.o second/cache.o second/prom.o second/file.o \ + second/partition.o second/fs.o second/cfg.o second/setjmp.o second/cmdline.o \ + second/fs_of.o second/fs_ext2.o second/fs_iso.o second/iso_util.o \ +- lib/nosys.o lib/string.o lib/strtol.o lib/vsprintf.o lib/ctype.o lib/malloc.o lib/strstr.o ++ second/sha256crypt.o second/sha512crypt.o \ ++ lib/nosys.o lib/string.o lib/strtol.o lib/vsprintf.o lib/ctype.o lib/malloc.o lib/stpncpy.o lib/strstr.o + + ifeq ($(USE_MD5_PASSWORDS),y) + OBJS += second/md5.o +diff -urN --exclude '*~' yaboot/man/yaboot.conf.5 yaboot-1.3.14/man/yaboot.conf.5 +--- yaboot/man/yaboot.conf.5 2010-01-12 22:39:21.565767002 +0100 ++++ yaboot-1.3.14/man/yaboot.conf.5 2010-01-13 17:10:00.334808308 +0100 +@@ -258,8 +258,9 @@ + .TP + .BI "password=" password + Protect booting by a password. The password is given in either +-cleartext or an md5 hash (of the same format as used in GNU/Linux +-passwd files)in the configuration file. Because of that, the ++cleartext or an hash (of the same format as used in GNU/Linux ++passwd files, using MD5, SHA-256 or SHA-512) in the configuration file. ++Because of that, the + configuration file should be only readable by the superuser and the + password should differ if possible from other passwords on the system. + See +diff -urN --exclude '*~' yaboot/second/sha256crypt.c yaboot-1.3.14/second/sha256crypt.c +--- yaboot/second/sha256crypt.c 1970-01-01 01:00:00.000000000 +0100 ++++ yaboot-1.3.14/second/sha256crypt.c 2010-01-13 16:56:46.453807903 +0100 +@@ -0,0 +1,735 @@ ++/* SHA256-based Unix crypt implementation. ++ Released into the Public Domain by Ulrich Drepper . ++ Adapted for yaboot by Miloslav Trmac . */ ++ ++#include ++#include "prom.h" ++#include "stdlib.h" ++#include "string.h" ++#include "types.h" ++ ++#define TEST ++typedef size_t uintptr_t; ++#define alloca(SIZE) (__builtin_alloca (SIZE)) ++#define MIN(a, b) ((a) < (b) ? (a) : (b)) ++#define MAX(a, b) ((a) > (b) ? (a) : (b)) ++ ++/* Structure to save state of computation between the single steps. */ ++struct sha256_ctx ++{ ++ uint32_t H[8]; ++ ++ uint32_t total[2]; ++ uint32_t buflen; ++ char buffer[128]; /* NB: always correctly aligned for uint32_t. */ ++}; ++ ++ ++#if 0 /* __BYTE_ORDER == __LITTLE_ENDIAN */ ++# define SWAP(n) \ ++ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) ++#else ++# define SWAP(n) (n) ++#endif ++ ++ ++/* This array contains the bytes used to pad the buffer to the next ++ 64-byte boundary. (FIPS 180-2:5.1.1) */ ++static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; ++ ++ ++/* Constants for SHA256 from FIPS 180-2:4.2.2. */ ++static const uint32_t K[64] = ++ { ++ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, ++ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, ++ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, ++ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, ++ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, ++ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, ++ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, ++ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, ++ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, ++ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, ++ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, ++ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, ++ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, ++ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, ++ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, ++ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ++ }; ++ ++ ++/* Process LEN bytes of BUFFER, accumulating context into CTX. ++ It is assumed that LEN % 64 == 0. */ ++static void ++sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx) ++{ ++ const uint32_t *words = buffer; ++ size_t nwords = len / sizeof (uint32_t); ++ uint32_t a = ctx->H[0]; ++ uint32_t b = ctx->H[1]; ++ uint32_t c = ctx->H[2]; ++ uint32_t d = ctx->H[3]; ++ uint32_t e = ctx->H[4]; ++ uint32_t f = ctx->H[5]; ++ uint32_t g = ctx->H[6]; ++ uint32_t h = ctx->H[7]; ++ ++ /* First increment the byte count. FIPS 180-2 specifies the possible ++ length of the file up to 2^64 bits. Here we only compute the ++ number of bytes. Do a double word increment. */ ++ ctx->total[0] += len; ++ if (ctx->total[0] < len) ++ ++ctx->total[1]; ++ ++ /* Process all bytes in the buffer with 64 bytes in each round of ++ the loop. */ ++ while (nwords > 0) ++ { ++ uint32_t W[64]; ++ uint32_t a_save = a; ++ uint32_t b_save = b; ++ uint32_t c_save = c; ++ uint32_t d_save = d; ++ uint32_t e_save = e; ++ uint32_t f_save = f; ++ uint32_t g_save = g; ++ uint32_t h_save = h; ++ unsigned int t; ++ ++ /* Operators defined in FIPS 180-2:4.1.2. */ ++#define Ch(x, y, z) ((x & y) ^ (~x & z)) ++#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) ++#define S0(x) (CYCLIC (x, 2) ^ CYCLIC (x, 13) ^ CYCLIC (x, 22)) ++#define S1(x) (CYCLIC (x, 6) ^ CYCLIC (x, 11) ^ CYCLIC (x, 25)) ++#define R0(x) (CYCLIC (x, 7) ^ CYCLIC (x, 18) ^ (x >> 3)) ++#define R1(x) (CYCLIC (x, 17) ^ CYCLIC (x, 19) ^ (x >> 10)) ++ ++ /* It is unfortunate that C does not provide an operator for ++ cyclic rotation. Hope the C compiler is smart enough. */ ++#define CYCLIC(w, s) ((w >> s) | (w << (32 - s))) ++ ++ /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */ ++ for (t = 0; t < 16; ++t) ++ { ++ W[t] = SWAP (*words); ++ ++words; ++ } ++ for (t = 16; t < 64; ++t) ++ W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; ++ ++ /* The actual computation according to FIPS 180-2:6.2.2 step 3. */ ++ for (t = 0; t < 64; ++t) ++ { ++ uint32_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; ++ uint32_t T2 = S0 (a) + Maj (a, b, c); ++ h = g; ++ g = f; ++ f = e; ++ e = d + T1; ++ d = c; ++ c = b; ++ b = a; ++ a = T1 + T2; ++ } ++ ++ /* Add the starting values of the context according to FIPS 180-2:6.2.2 ++ step 4. */ ++ a += a_save; ++ b += b_save; ++ c += c_save; ++ d += d_save; ++ e += e_save; ++ f += f_save; ++ g += g_save; ++ h += h_save; ++ ++ /* Prepare for the next round. */ ++ nwords -= 16; ++ } ++ ++ /* Put checksum in context given as argument. */ ++ ctx->H[0] = a; ++ ctx->H[1] = b; ++ ctx->H[2] = c; ++ ctx->H[3] = d; ++ ctx->H[4] = e; ++ ctx->H[5] = f; ++ ctx->H[6] = g; ++ ctx->H[7] = h; ++} ++ ++ ++/* Initialize structure containing state of computation. ++ (FIPS 180-2:5.3.2) */ ++static void ++sha256_init_ctx (struct sha256_ctx *ctx) ++{ ++ ctx->H[0] = 0x6a09e667; ++ ctx->H[1] = 0xbb67ae85; ++ ctx->H[2] = 0x3c6ef372; ++ ctx->H[3] = 0xa54ff53a; ++ ctx->H[4] = 0x510e527f; ++ ctx->H[5] = 0x9b05688c; ++ ctx->H[6] = 0x1f83d9ab; ++ ctx->H[7] = 0x5be0cd19; ++ ++ ctx->total[0] = ctx->total[1] = 0; ++ ctx->buflen = 0; ++} ++ ++ ++/* Process the remaining bytes in the internal buffer and the usual ++ prolog according to the standard and write the result to RESBUF. ++ ++ IMPORTANT: On some systems it is required that RESBUF is correctly ++ aligned for a 32 bits value. */ ++static void * ++sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf) ++{ ++ /* Take yet unprocessed bytes into account. */ ++ uint32_t bytes = ctx->buflen; ++ size_t pad; ++ unsigned int i; ++ ++ /* Now count remaining bytes. */ ++ ctx->total[0] += bytes; ++ if (ctx->total[0] < bytes) ++ ++ctx->total[1]; ++ ++ pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; ++ memcpy (&ctx->buffer[bytes], fillbuf, pad); ++ ++ /* Put the 64-bit file length in *bits* at the end of the buffer. */ ++ *(uint32_t *) &ctx->buffer[bytes + pad + 4] = SWAP (ctx->total[0] << 3); ++ *(uint32_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) | ++ (ctx->total[0] >> 29)); ++ ++ /* Process last bytes. */ ++ sha256_process_block (ctx->buffer, bytes + pad + 8, ctx); ++ ++ /* Put result from CTX in first 32 bytes following RESBUF. */ ++ for (i = 0; i < 8; ++i) ++ ((uint32_t *) resbuf)[i] = SWAP (ctx->H[i]); ++ ++ return resbuf; ++} ++ ++ ++static void ++sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx) ++{ ++ /* When we already have some bits in our internal buffer concatenate ++ both inputs first. */ ++ if (ctx->buflen != 0) ++ { ++ size_t left_over = ctx->buflen; ++ size_t add = 128 - left_over > len ? len : 128 - left_over; ++ ++ memcpy (&ctx->buffer[left_over], buffer, add); ++ ctx->buflen += add; ++ ++ if (ctx->buflen > 64) ++ { ++ sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx); ++ ++ ctx->buflen &= 63; ++ /* The regions in the following copy operation cannot overlap. */ ++ memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], ++ ctx->buflen); ++ } ++ ++ buffer = (const char *) buffer + add; ++ len -= add; ++ } ++ ++ /* Process available complete blocks. */ ++ if (len >= 64) ++ { ++/* To check alignment gcc has an appropriate operator. Other ++ compilers don't. */ ++#if __GNUC__ >= 2 ++# define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint32_t) != 0) ++#else ++# define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint32_t) != 0) ++#endif ++ if (UNALIGNED_P (buffer)) ++ while (len > 64) ++ { ++ sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); ++ buffer = (const char *) buffer + 64; ++ len -= 64; ++ } ++ else ++ { ++ sha256_process_block (buffer, len & ~63, ctx); ++ buffer = (const char *) buffer + (len & ~63); ++ len &= 63; ++ } ++ } ++ ++ /* Move remaining bytes into internal buffer. */ ++ if (len > 0) ++ { ++ size_t left_over = ctx->buflen; ++ ++ memcpy (&ctx->buffer[left_over], buffer, len); ++ left_over += len; ++ if (left_over >= 64) ++ { ++ sha256_process_block (ctx->buffer, 64, ctx); ++ left_over -= 64; ++ memcpy (ctx->buffer, &ctx->buffer[64], left_over); ++ } ++ ctx->buflen = left_over; ++ } ++} ++ ++ ++/* Define our magic string to mark salt for SHA256 "encryption" ++ replacement. */ ++static const char sha256_salt_prefix[] = "$5$"; ++ ++/* Prefix for optional rounds specification. */ ++static const char sha256_rounds_prefix[] = "rounds="; ++ ++/* Maximum salt string length. */ ++#define SALT_LEN_MAX 16 ++/* Default number of rounds if not explicitly specified. */ ++#define ROUNDS_DEFAULT 5000 ++/* Minimum number of rounds. */ ++#define ROUNDS_MIN 1000 ++/* Maximum number of rounds. */ ++#define ROUNDS_MAX 999999999 ++ ++/* Table with characters for base64 transformation. */ ++static const char b64t[64] = ++"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; ++ ++ ++static char * ++sha256_crypt_r (const char *key, const char *salt, char *buffer, int buflen) ++{ ++ unsigned char alt_result[32] ++ __attribute__ ((__aligned__ (__alignof__ (uint32_t)))); ++ unsigned char temp_result[32] ++ __attribute__ ((__aligned__ (__alignof__ (uint32_t)))); ++ struct sha256_ctx ctx; ++ struct sha256_ctx alt_ctx; ++ size_t salt_len; ++ size_t key_len; ++ size_t cnt; ++ char *cp; ++ char *copied_key = NULL; ++ char *copied_salt = NULL; ++ char *p_bytes; ++ char *s_bytes; ++ /* Default number of rounds. */ ++ size_t rounds = ROUNDS_DEFAULT; ++ bool rounds_custom = false; ++ ++ /* Find beginning of salt string. The prefix should normally always ++ be present. Just in case it is not. */ ++ if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0) ++ /* Skip salt prefix. */ ++ salt += sizeof (sha256_salt_prefix) - 1; ++ ++ if (strncmp (salt, sha256_rounds_prefix, sizeof (sha256_rounds_prefix) - 1) ++ == 0) ++ { ++ const char *num = salt + sizeof (sha256_rounds_prefix) - 1; ++ char *endp; ++ unsigned long int srounds = (unsigned long)strtol (num, &endp, 10); ++ if (*endp == '$') ++ { ++ salt = endp + 1; ++ rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX)); ++ rounds_custom = true; ++ } ++ } ++ ++ { ++ char *salt_end; ++ ++ salt_end = strchr (salt, '$'); ++ if (salt_end == NULL) ++ salt_end = strchr (salt, '\0'); ++ salt_len = salt_end - salt; ++ } ++ salt_len = MIN (salt_len, SALT_LEN_MAX); ++ key_len = strlen (key); ++ ++ if ((key - (char *) 0) % __alignof__ (uint32_t) != 0) ++ { ++ char *tmp = (char *) alloca (key_len + __alignof__ (uint32_t)); ++ key = copied_key = ++ memcpy (tmp + __alignof__ (uint32_t) ++ - (tmp - (char *) 0) % __alignof__ (uint32_t), ++ key, key_len); ++ } ++ ++ if ((salt - (char *) 0) % __alignof__ (uint32_t) != 0) ++ { ++ char *tmp = (char *) alloca (salt_len + __alignof__ (uint32_t)); ++ salt = copied_salt = ++ memcpy (tmp + __alignof__ (uint32_t) ++ - (tmp - (char *) 0) % __alignof__ (uint32_t), ++ salt, salt_len); ++ } ++ ++ /* Prepare for the real work. */ ++ sha256_init_ctx (&ctx); ++ ++ /* Add the key string. */ ++ sha256_process_bytes (key, key_len, &ctx); ++ ++ /* The last part is the salt string. This must be at most 16 ++ characters and it ends at the first `$' character (for ++ compatibility with existing implementations). */ ++ sha256_process_bytes (salt, salt_len, &ctx); ++ ++ ++ /* Compute alternate SHA256 sum with input KEY, SALT, and KEY. The ++ final result will be added to the first context. */ ++ sha256_init_ctx (&alt_ctx); ++ ++ /* Add key. */ ++ sha256_process_bytes (key, key_len, &alt_ctx); ++ ++ /* Add salt. */ ++ sha256_process_bytes (salt, salt_len, &alt_ctx); ++ ++ /* Add key again. */ ++ sha256_process_bytes (key, key_len, &alt_ctx); ++ ++ /* Now get result of this (32 bytes) and add it to the other ++ context. */ ++ sha256_finish_ctx (&alt_ctx, alt_result); ++ ++ /* Add for any character in the key one byte of the alternate sum. */ ++ for (cnt = key_len; cnt > 32; cnt -= 32) ++ sha256_process_bytes (alt_result, 32, &ctx); ++ sha256_process_bytes (alt_result, cnt, &ctx); ++ ++ /* Take the binary representation of the length of the key and for every ++ 1 add the alternate sum, for every 0 the key. */ ++ for (cnt = key_len; cnt > 0; cnt >>= 1) ++ if ((cnt & 1) != 0) ++ sha256_process_bytes (alt_result, 32, &ctx); ++ else ++ sha256_process_bytes (key, key_len, &ctx); ++ ++ /* Create intermediate result. */ ++ sha256_finish_ctx (&ctx, alt_result); ++ ++ /* Start computation of P byte sequence. */ ++ sha256_init_ctx (&alt_ctx); ++ ++ /* For every character in the password add the entire password. */ ++ for (cnt = 0; cnt < key_len; ++cnt) ++ sha256_process_bytes (key, key_len, &alt_ctx); ++ ++ /* Finish the digest. */ ++ sha256_finish_ctx (&alt_ctx, temp_result); ++ ++ /* Create byte sequence P. */ ++ cp = p_bytes = alloca (key_len); ++ for (cnt = key_len; cnt >= 32; cnt -= 32) ++ { ++ memcpy (cp, temp_result, 32); ++ cp += 32; ++ } ++ memcpy (cp, temp_result, cnt); ++ ++ /* Start computation of S byte sequence. */ ++ sha256_init_ctx (&alt_ctx); ++ ++ /* For every character in the password add the entire password. */ ++ for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt) ++ sha256_process_bytes (salt, salt_len, &alt_ctx); ++ ++ /* Finish the digest. */ ++ sha256_finish_ctx (&alt_ctx, temp_result); ++ ++ /* Create byte sequence S. */ ++ cp = s_bytes = alloca (salt_len); ++ for (cnt = salt_len; cnt >= 32; cnt -= 32) ++ { ++ memcpy (cp, temp_result, 32); ++ cp += 32; ++ } ++ memcpy (cp, temp_result, cnt); ++ ++ /* Repeatedly run the collected hash value through SHA256 to burn ++ CPU cycles. */ ++ for (cnt = 0; cnt < rounds; ++cnt) ++ { ++ /* New context. */ ++ sha256_init_ctx (&ctx); ++ ++ /* Add key or last result. */ ++ if ((cnt & 1) != 0) ++ sha256_process_bytes (p_bytes, key_len, &ctx); ++ else ++ sha256_process_bytes (alt_result, 32, &ctx); ++ ++ /* Add salt for numbers not divisible by 3. */ ++ if (cnt % 3 != 0) ++ sha256_process_bytes (s_bytes, salt_len, &ctx); ++ ++ /* Add key for numbers not divisible by 7. */ ++ if (cnt % 7 != 0) ++ sha256_process_bytes (p_bytes, key_len, &ctx); ++ ++ /* Add key or last result. */ ++ if ((cnt & 1) != 0) ++ sha256_process_bytes (alt_result, 32, &ctx); ++ else ++ sha256_process_bytes (p_bytes, key_len, &ctx); ++ ++ /* Create intermediate result. */ ++ sha256_finish_ctx (&ctx, alt_result); ++ } ++ ++ /* Now we can construct the result string. It consists of three ++ parts. */ ++ cp = stpncpy (buffer, sha256_salt_prefix, MAX (0, buflen)); ++ buflen -= sizeof (sha256_salt_prefix) - 1; ++ ++ if (rounds_custom) ++ { ++ char sbuf[64]; ++ sprintf (sbuf, "%s%Lu$", sha256_rounds_prefix, ++ (unsigned long long)rounds); ++ size_t n = strlen (sbuf); ++ memcpy (cp, sbuf, MIN (MAX (0, buflen), n)); ++ cp += n; ++ buflen -= n; ++ } ++ ++ cp = stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len)); ++ buflen -= MIN ((size_t) MAX (0, buflen), salt_len); ++ ++ if (buflen > 0) ++ { ++ *cp++ = '$'; ++ --buflen; ++ } ++ ++#define b64_from_24bit(B2, B1, B0, N) \ ++ do { \ ++ unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \ ++ int n = (N); \ ++ while (n-- > 0 && buflen > 0) \ ++ { \ ++ *cp++ = b64t[w & 0x3f]; \ ++ --buflen; \ ++ w >>= 6; \ ++ } \ ++ } while (0) ++ ++ b64_from_24bit (alt_result[0], alt_result[10], alt_result[20], 4); ++ b64_from_24bit (alt_result[21], alt_result[1], alt_result[11], 4); ++ b64_from_24bit (alt_result[12], alt_result[22], alt_result[2], 4); ++ b64_from_24bit (alt_result[3], alt_result[13], alt_result[23], 4); ++ b64_from_24bit (alt_result[24], alt_result[4], alt_result[14], 4); ++ b64_from_24bit (alt_result[15], alt_result[25], alt_result[5], 4); ++ b64_from_24bit (alt_result[6], alt_result[16], alt_result[26], 4); ++ b64_from_24bit (alt_result[27], alt_result[7], alt_result[17], 4); ++ b64_from_24bit (alt_result[18], alt_result[28], alt_result[8], 4); ++ b64_from_24bit (alt_result[9], alt_result[19], alt_result[29], 4); ++ b64_from_24bit (0, alt_result[31], alt_result[30], 3); ++ if (buflen <= 0) ++ buffer = NULL; ++ else ++ *cp = '\0'; /* Terminate the string. */ ++ ++ /* Clear the buffer for the intermediate result so that people ++ attaching to processes or reading core dumps cannot get any ++ information. We do it in this way to clear correct_words[] ++ inside the SHA256 implementation as well. */ ++ sha256_init_ctx (&ctx); ++ sha256_finish_ctx (&ctx, alt_result); ++ memset (temp_result, '\0', sizeof (temp_result)); ++ memset (p_bytes, '\0', key_len); ++ memset (s_bytes, '\0', salt_len); ++ memset (&ctx, '\0', sizeof (ctx)); ++ memset (&alt_ctx, '\0', sizeof (alt_ctx)); ++ if (copied_key != NULL) ++ memset (copied_key, '\0', key_len); ++ if (copied_salt != NULL) ++ memset (copied_salt, '\0', salt_len); ++ ++ return buffer; ++} ++ ++ ++/* This entry point is equivalent to the `crypt' function in Unix ++ libcs. */ ++char * ++sha256_crypt (const char *key, const char *salt) ++{ ++ /* We don't want to have an arbitrary limit in the size of the ++ password. We can compute an upper bound for the size of the ++ result in advance and so we can prepare the buffer we pass to ++ `sha256_crypt_r'. */ ++ static char *buffer; ++ static int buflen; ++ int needed = (sizeof (sha256_salt_prefix) - 1 ++ + sizeof (sha256_rounds_prefix) + 9 + 1 ++ + strlen (salt) + 1 + 43 + 1); ++ ++ if (buflen < needed) ++ { ++ char *new_buffer = (char *) realloc (buffer, needed); ++ if (new_buffer == NULL) ++ return NULL; ++ ++ buffer = new_buffer; ++ buflen = needed; ++ } ++ ++ return sha256_crypt_r (key, salt, buffer, buflen); ++} ++ ++ ++#ifdef TEST ++static const struct ++{ ++ const char *input; ++ const char result[32]; ++} tests[] = ++ { ++ /* Test vectors from FIPS 180-2: appendix B.1. */ ++ { "abc", ++ "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23" ++ "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" }, ++ /* Test vectors from FIPS 180-2: appendix B.2. */ ++ { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", ++ "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39" ++ "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" }, ++ /* Test vectors from the NESSIE project. */ ++ { "", ++ "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24" ++ "\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55" }, ++ { "a", ++ "\xca\x97\x81\x12\xca\x1b\xbd\xca\xfa\xc2\x31\xb3\x9a\x23\xdc\x4d" ++ "\xa7\x86\xef\xf8\x14\x7c\x4e\x72\xb9\x80\x77\x85\xaf\xee\x48\xbb" }, ++ { "message digest", ++ "\xf7\x84\x6f\x55\xcf\x23\xe1\x4e\xeb\xea\xb5\xb4\xe1\x55\x0c\xad" ++ "\x5b\x50\x9e\x33\x48\xfb\xc4\xef\xa3\xa1\x41\x3d\x39\x3c\xb6\x50" }, ++ { "abcdefghijklmnopqrstuvwxyz", ++ "\x71\xc4\x80\xdf\x93\xd6\xae\x2f\x1e\xfa\xd1\x44\x7c\x66\xc9\x52" ++ "\x5e\x31\x62\x18\xcf\x51\xfc\x8d\x9e\xd8\x32\xf2\xda\xf1\x8b\x73" }, ++ { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", ++ "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39" ++ "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" }, ++ { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", ++ "\xdb\x4b\xfc\xbd\x4d\xa0\xcd\x85\xa6\x0c\x3c\x37\xd3\xfb\xd8\x80" ++ "\x5c\x77\xf1\x5f\xc6\xb1\xfd\xfe\x61\x4e\xe0\xa7\xc8\xfd\xb4\xc0" }, ++ { "123456789012345678901234567890123456789012345678901234567890" ++ "12345678901234567890", ++ "\xf3\x71\xbc\x4a\x31\x1f\x2b\x00\x9e\xef\x95\x2d\xd8\x3c\xa8\x0e" ++ "\x2b\x60\x02\x6c\x8e\x93\x55\x92\xd0\xf9\xc3\x08\x45\x3c\x81\x3e" } ++ }; ++#define ntests (sizeof (tests) / sizeof (tests[0])) ++ ++ ++static const struct ++{ ++ const char *salt; ++ const char *input; ++ const char *expected; ++} tests2[] = ++{ ++ { "$5$saltstring", "Hello world!", ++ "$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5" }, ++ { "$5$rounds=10000$saltstringsaltstring", "Hello world!", ++ "$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2." ++ "opqey6IcA" }, ++ { "$5$rounds=5000$toolongsaltstring", "This is just a test", ++ "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8" ++ "mGRcvxa5" }, ++ { "$5$rounds=1400$anotherlongsaltstring", ++ "a very much longer text to encrypt. This one even stretches over more" ++ "than one line.", ++ "$5$rounds=1400$anotherlongsalts$Rx.j8H.h8HjEDGomFU8bDkXm3XIUnzyxf12" ++ "oP84Bnq1" }, ++ { "$5$rounds=77777$short", ++ "we have a short salt string but not a short password", ++ "$5$rounds=77777$short$JiO1O3ZpDAxGJeaDIuqCoEFysAe1mZNJRs3pw0KQRd/" }, ++ { "$5$rounds=123456$asaltof16chars..", "a short string", ++ "$5$rounds=123456$asaltof16chars..$gP3VQ/6X7UUEW3HkBn2w1/Ptq2jxPyzV/" ++ "cZKmF/wJvD" }, ++ { "$5$rounds=10$roundstoolow", "the minimum number is still observed", ++ "$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL97" ++ "2bIC" }, ++}; ++#define ntests2 (sizeof (tests2) / sizeof (tests2[0])) ++ ++ ++int ++sha256_test (void) ++{ ++ struct sha256_ctx ctx; ++ char sum[32]; ++ int result = 0; ++ int cnt, i; ++ ++ for (cnt = 0; cnt < (int) ntests; ++cnt) ++ { ++ sha256_init_ctx (&ctx); ++ sha256_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx); ++ sha256_finish_ctx (&ctx, sum); ++ if (memcmp (tests[cnt].result, sum, 32) != 0) ++ { ++ prom_printf ("test %d run %d failed\n", cnt, 1); ++ result = 1; ++ } ++ ++ sha256_init_ctx (&ctx); ++ for (i = 0; tests[cnt].input[i] != '\0'; ++i) ++ sha256_process_bytes (&tests[cnt].input[i], 1, &ctx); ++ sha256_finish_ctx (&ctx, sum); ++ if (memcmp (tests[cnt].result, sum, 32) != 0) ++ { ++ prom_printf ("test %d run %d failed\n", cnt, 2); ++ result = 1; ++ } ++ } ++ ++ /* Test vector from FIPS 180-2: appendix B.3. */ ++ char buf[1000]; ++ memset (buf, 'a', sizeof (buf)); ++ sha256_init_ctx (&ctx); ++ for (i = 0; i < 1000; ++i) ++ sha256_process_bytes (buf, sizeof (buf), &ctx); ++ sha256_finish_ctx (&ctx, sum); ++ static const char expected[32] = ++ "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67" ++ "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0"; ++ if (memcmp (expected, sum, 32) != 0) ++ { ++ prom_printf ("test %d failed\n", cnt); ++ result = 1; ++ } ++ ++ for (cnt = 0; cnt < ntests2; ++cnt) ++ { ++ char *cp = sha256_crypt (tests2[cnt].input, tests2[cnt].salt); ++ ++ if (strcmp (cp, tests2[cnt].expected) != 0) ++ { ++ prom_printf ("test %d: expected \"%s\", got \"%s\"\n", ++ cnt, tests2[cnt].expected, cp); ++ result = 1; ++ } ++ } ++ ++ if (result == 0) ++ prom_printf ("all tests OK\n"); ++ ++ return result; ++} ++#endif +diff -urN --exclude '*~' yaboot/second/sha512crypt.c yaboot-1.3.14/second/sha512crypt.c +--- yaboot/second/sha512crypt.c 1970-01-01 01:00:00.000000000 +0100 ++++ yaboot-1.3.14/second/sha512crypt.c 2010-01-13 16:56:43.390807820 +0100 +@@ -0,0 +1,804 @@ ++/* SHA512-based Unix crypt implementation. ++ Released into the Public Domain by Ulrich Drepper . ++ Adapted for yaboot by Miloslav Trmac . */ ++ ++#include ++#include "prom.h" ++#include "stdlib.h" ++#include "string.h" ++#include "types.h" ++ ++#define TEST ++typedef size_t uintptr_t; ++#define UINT64_C(X) X ## ULL ++#define alloca(SIZE) (__builtin_alloca (SIZE)) ++#define MIN(a, b) ((a) < (b) ? (a) : (b)) ++#define MAX(a, b) ((a) > (b) ? (a) : (b)) ++ ++/* Structure to save state of computation between the single steps. */ ++struct sha512_ctx ++{ ++ uint64_t H[8]; ++ ++ uint64_t total[2]; ++ uint64_t buflen; ++ char buffer[256]; /* NB: always correctly aligned for uint64_t. */ ++}; ++ ++ ++#if 0 /* __BYTE_ORDER == __LITTLE_ENDIAN */ ++# define SWAP(n) \ ++ (((n) << 56) \ ++ | (((n) & 0xff00) << 40) \ ++ | (((n) & 0xff0000) << 24) \ ++ | (((n) & 0xff000000) << 8) \ ++ | (((n) >> 8) & 0xff000000) \ ++ | (((n) >> 24) & 0xff0000) \ ++ | (((n) >> 40) & 0xff00) \ ++ | ((n) >> 56)) ++#else ++# define SWAP(n) (n) ++#endif ++ ++ ++/* This array contains the bytes used to pad the buffer to the next ++ 64-byte boundary. (FIPS 180-2:5.1.2) */ ++static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ }; ++ ++ ++/* Constants for SHA512 from FIPS 180-2:4.2.3. */ ++static const uint64_t K[80] = ++ { ++ UINT64_C (0x428a2f98d728ae22), UINT64_C (0x7137449123ef65cd), ++ UINT64_C (0xb5c0fbcfec4d3b2f), UINT64_C (0xe9b5dba58189dbbc), ++ UINT64_C (0x3956c25bf348b538), UINT64_C (0x59f111f1b605d019), ++ UINT64_C (0x923f82a4af194f9b), UINT64_C (0xab1c5ed5da6d8118), ++ UINT64_C (0xd807aa98a3030242), UINT64_C (0x12835b0145706fbe), ++ UINT64_C (0x243185be4ee4b28c), UINT64_C (0x550c7dc3d5ffb4e2), ++ UINT64_C (0x72be5d74f27b896f), UINT64_C (0x80deb1fe3b1696b1), ++ UINT64_C (0x9bdc06a725c71235), UINT64_C (0xc19bf174cf692694), ++ UINT64_C (0xe49b69c19ef14ad2), UINT64_C (0xefbe4786384f25e3), ++ UINT64_C (0x0fc19dc68b8cd5b5), UINT64_C (0x240ca1cc77ac9c65), ++ UINT64_C (0x2de92c6f592b0275), UINT64_C (0x4a7484aa6ea6e483), ++ UINT64_C (0x5cb0a9dcbd41fbd4), UINT64_C (0x76f988da831153b5), ++ UINT64_C (0x983e5152ee66dfab), UINT64_C (0xa831c66d2db43210), ++ UINT64_C (0xb00327c898fb213f), UINT64_C (0xbf597fc7beef0ee4), ++ UINT64_C (0xc6e00bf33da88fc2), UINT64_C (0xd5a79147930aa725), ++ UINT64_C (0x06ca6351e003826f), UINT64_C (0x142929670a0e6e70), ++ UINT64_C (0x27b70a8546d22ffc), UINT64_C (0x2e1b21385c26c926), ++ UINT64_C (0x4d2c6dfc5ac42aed), UINT64_C (0x53380d139d95b3df), ++ UINT64_C (0x650a73548baf63de), UINT64_C (0x766a0abb3c77b2a8), ++ UINT64_C (0x81c2c92e47edaee6), UINT64_C (0x92722c851482353b), ++ UINT64_C (0xa2bfe8a14cf10364), UINT64_C (0xa81a664bbc423001), ++ UINT64_C (0xc24b8b70d0f89791), UINT64_C (0xc76c51a30654be30), ++ UINT64_C (0xd192e819d6ef5218), UINT64_C (0xd69906245565a910), ++ UINT64_C (0xf40e35855771202a), UINT64_C (0x106aa07032bbd1b8), ++ UINT64_C (0x19a4c116b8d2d0c8), UINT64_C (0x1e376c085141ab53), ++ UINT64_C (0x2748774cdf8eeb99), UINT64_C (0x34b0bcb5e19b48a8), ++ UINT64_C (0x391c0cb3c5c95a63), UINT64_C (0x4ed8aa4ae3418acb), ++ UINT64_C (0x5b9cca4f7763e373), UINT64_C (0x682e6ff3d6b2b8a3), ++ UINT64_C (0x748f82ee5defb2fc), UINT64_C (0x78a5636f43172f60), ++ UINT64_C (0x84c87814a1f0ab72), UINT64_C (0x8cc702081a6439ec), ++ UINT64_C (0x90befffa23631e28), UINT64_C (0xa4506cebde82bde9), ++ UINT64_C (0xbef9a3f7b2c67915), UINT64_C (0xc67178f2e372532b), ++ UINT64_C (0xca273eceea26619c), UINT64_C (0xd186b8c721c0c207), ++ UINT64_C (0xeada7dd6cde0eb1e), UINT64_C (0xf57d4f7fee6ed178), ++ UINT64_C (0x06f067aa72176fba), UINT64_C (0x0a637dc5a2c898a6), ++ UINT64_C (0x113f9804bef90dae), UINT64_C (0x1b710b35131c471b), ++ UINT64_C (0x28db77f523047d84), UINT64_C (0x32caab7b40c72493), ++ UINT64_C (0x3c9ebe0a15c9bebc), UINT64_C (0x431d67c49c100d4c), ++ UINT64_C (0x4cc5d4becb3e42b6), UINT64_C (0x597f299cfc657e2a), ++ UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817) ++ }; ++ ++ ++/* Process LEN bytes of BUFFER, accumulating context into CTX. ++ It is assumed that LEN % 128 == 0. */ ++static void ++sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx) ++{ ++ const uint64_t *words = buffer; ++ size_t nwords = len / sizeof (uint64_t); ++ uint64_t a = ctx->H[0]; ++ uint64_t b = ctx->H[1]; ++ uint64_t c = ctx->H[2]; ++ uint64_t d = ctx->H[3]; ++ uint64_t e = ctx->H[4]; ++ uint64_t f = ctx->H[5]; ++ uint64_t g = ctx->H[6]; ++ uint64_t h = ctx->H[7]; ++ ++ /* First increment the byte count. FIPS 180-2 specifies the possible ++ length of the file up to 2^128 bits. Here we only compute the ++ number of bytes. Do a double word increment. */ ++ ctx->total[0] += len; ++ if (ctx->total[0] < len) ++ ++ctx->total[1]; ++ ++ /* Process all bytes in the buffer with 128 bytes in each round of ++ the loop. */ ++ while (nwords > 0) ++ { ++ uint64_t W[80]; ++ uint64_t a_save = a; ++ uint64_t b_save = b; ++ uint64_t c_save = c; ++ uint64_t d_save = d; ++ uint64_t e_save = e; ++ uint64_t f_save = f; ++ uint64_t g_save = g; ++ uint64_t h_save = h; ++ unsigned int t; ++ ++ /* Operators defined in FIPS 180-2:4.1.2. */ ++#define Ch(x, y, z) ((x & y) ^ (~x & z)) ++#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) ++#define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39)) ++#define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41)) ++#define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7)) ++#define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6)) ++ ++ /* It is unfortunate that C does not provide an operator for ++ cyclic rotation. Hope the C compiler is smart enough. */ ++#define CYCLIC(w, s) ((w >> s) | (w << (64 - s))) ++ ++ /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */ ++ for (t = 0; t < 16; ++t) ++ { ++ W[t] = SWAP (*words); ++ ++words; ++ } ++ for (t = 16; t < 80; ++t) ++ W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; ++ ++ /* The actual computation according to FIPS 180-2:6.3.2 step 3. */ ++ for (t = 0; t < 80; ++t) ++ { ++ uint64_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; ++ uint64_t T2 = S0 (a) + Maj (a, b, c); ++ h = g; ++ g = f; ++ f = e; ++ e = d + T1; ++ d = c; ++ c = b; ++ b = a; ++ a = T1 + T2; ++ } ++ ++ /* Add the starting values of the context according to FIPS 180-2:6.3.2 ++ step 4. */ ++ a += a_save; ++ b += b_save; ++ c += c_save; ++ d += d_save; ++ e += e_save; ++ f += f_save; ++ g += g_save; ++ h += h_save; ++ ++ /* Prepare for the next round. */ ++ nwords -= 16; ++ } ++ ++ /* Put checksum in context given as argument. */ ++ ctx->H[0] = a; ++ ctx->H[1] = b; ++ ctx->H[2] = c; ++ ctx->H[3] = d; ++ ctx->H[4] = e; ++ ctx->H[5] = f; ++ ctx->H[6] = g; ++ ctx->H[7] = h; ++} ++ ++ ++/* Initialize structure containing state of computation. ++ (FIPS 180-2:5.3.3) */ ++static void ++sha512_init_ctx (struct sha512_ctx *ctx) ++{ ++ ctx->H[0] = UINT64_C (0x6a09e667f3bcc908); ++ ctx->H[1] = UINT64_C (0xbb67ae8584caa73b); ++ ctx->H[2] = UINT64_C (0x3c6ef372fe94f82b); ++ ctx->H[3] = UINT64_C (0xa54ff53a5f1d36f1); ++ ctx->H[4] = UINT64_C (0x510e527fade682d1); ++ ctx->H[5] = UINT64_C (0x9b05688c2b3e6c1f); ++ ctx->H[6] = UINT64_C (0x1f83d9abfb41bd6b); ++ ctx->H[7] = UINT64_C (0x5be0cd19137e2179); ++ ++ ctx->total[0] = ctx->total[1] = 0; ++ ctx->buflen = 0; ++} ++ ++ ++/* Process the remaining bytes in the internal buffer and the usual ++ prolog according to the standard and write the result to RESBUF. ++ ++ IMPORTANT: On some systems it is required that RESBUF is correctly ++ aligned for a 32 bits value. */ ++static void * ++sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf) ++{ ++ /* Take yet unprocessed bytes into account. */ ++ uint64_t bytes = ctx->buflen; ++ size_t pad; ++ unsigned int i; ++ ++ /* Now count remaining bytes. */ ++ ctx->total[0] += bytes; ++ if (ctx->total[0] < bytes) ++ ++ctx->total[1]; ++ ++ pad = bytes >= 112 ? 128 + 112 - bytes : 112 - bytes; ++ memcpy (&ctx->buffer[bytes], fillbuf, pad); ++ ++ /* Put the 128-bit file length in *bits* at the end of the buffer. */ ++ *(uint64_t *) &ctx->buffer[bytes + pad + 8] = SWAP (ctx->total[0] << 3); ++ *(uint64_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) | ++ (ctx->total[0] >> 61)); ++ ++ /* Process last bytes. */ ++ sha512_process_block (ctx->buffer, bytes + pad + 16, ctx); ++ ++ /* Put result from CTX in first 64 bytes following RESBUF. */ ++ for (i = 0; i < 8; ++i) ++ ((uint64_t *) resbuf)[i] = SWAP (ctx->H[i]); ++ ++ return resbuf; ++} ++ ++ ++static void ++sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx) ++{ ++ /* When we already have some bits in our internal buffer concatenate ++ both inputs first. */ ++ if (ctx->buflen != 0) ++ { ++ size_t left_over = ctx->buflen; ++ size_t add = 256 - left_over > len ? len : 256 - left_over; ++ ++ memcpy (&ctx->buffer[left_over], buffer, add); ++ ctx->buflen += add; ++ ++ if (ctx->buflen > 128) ++ { ++ sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx); ++ ++ ctx->buflen &= 127; ++ /* The regions in the following copy operation cannot overlap. */ ++ memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~127], ++ ctx->buflen); ++ } ++ ++ buffer = (const char *) buffer + add; ++ len -= add; ++ } ++ ++ /* Process available complete blocks. */ ++ if (len >= 128) ++ { ++#if !_STRING_ARCH_unaligned ++/* To check alignment gcc has an appropriate operator. Other ++ compilers don't. */ ++# if __GNUC__ >= 2 ++# define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint64_t) != 0) ++# else ++# define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint64_t) != 0) ++# endif ++ if (UNALIGNED_P (buffer)) ++ while (len > 128) ++ { ++ sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128, ++ ctx); ++ buffer = (const char *) buffer + 128; ++ len -= 128; ++ } ++ else ++#endif ++ { ++ sha512_process_block (buffer, len & ~127, ctx); ++ buffer = (const char *) buffer + (len & ~127); ++ len &= 127; ++ } ++ } ++ ++ /* Move remaining bytes into internal buffer. */ ++ if (len > 0) ++ { ++ size_t left_over = ctx->buflen; ++ ++ memcpy (&ctx->buffer[left_over], buffer, len); ++ left_over += len; ++ if (left_over >= 128) ++ { ++ sha512_process_block (ctx->buffer, 128, ctx); ++ left_over -= 128; ++ memcpy (ctx->buffer, &ctx->buffer[128], left_over); ++ } ++ ctx->buflen = left_over; ++ } ++} ++ ++ ++/* Define our magic string to mark salt for SHA512 "encryption" ++ replacement. */ ++static const char sha512_salt_prefix[] = "$6$"; ++ ++/* Prefix for optional rounds specification. */ ++static const char sha512_rounds_prefix[] = "rounds="; ++ ++/* Maximum salt string length. */ ++#define SALT_LEN_MAX 16 ++/* Default number of rounds if not explicitly specified. */ ++#define ROUNDS_DEFAULT 5000 ++/* Minimum number of rounds. */ ++#define ROUNDS_MIN 1000 ++/* Maximum number of rounds. */ ++#define ROUNDS_MAX 999999999 ++ ++/* Table with characters for base64 transformation. */ ++static const char b64t[64] = ++"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; ++ ++ ++static char * ++sha512_crypt_r (const char *key, const char *salt, char *buffer, int buflen) ++{ ++ unsigned char alt_result[64] ++ __attribute__ ((__aligned__ (__alignof__ (uint64_t)))); ++ unsigned char temp_result[64] ++ __attribute__ ((__aligned__ (__alignof__ (uint64_t)))); ++ struct sha512_ctx ctx; ++ struct sha512_ctx alt_ctx; ++ size_t salt_len; ++ size_t key_len; ++ size_t cnt; ++ char *cp; ++ char *copied_key = NULL; ++ char *copied_salt = NULL; ++ char *p_bytes; ++ char *s_bytes; ++ /* Default number of rounds. */ ++ size_t rounds = ROUNDS_DEFAULT; ++ bool rounds_custom = false; ++ ++ /* Find beginning of salt string. The prefix should normally always ++ be present. Just in case it is not. */ ++ if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0) ++ /* Skip salt prefix. */ ++ salt += sizeof (sha512_salt_prefix) - 1; ++ ++ if (strncmp (salt, sha512_rounds_prefix, sizeof (sha512_rounds_prefix) - 1) ++ == 0) ++ { ++ const char *num = salt + sizeof (sha512_rounds_prefix) - 1; ++ char *endp; ++ unsigned long int srounds = (unsigned long)strtol (num, &endp, 10); ++ if (*endp == '$') ++ { ++ salt = endp + 1; ++ rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX)); ++ rounds_custom = true; ++ } ++ } ++ ++ { ++ char *salt_end; ++ ++ salt_end = strchr (salt, '$'); ++ if (salt_end == NULL) ++ salt_end = strchr (salt, '\0'); ++ salt_len = salt_end - salt; ++ } ++ key_len = strlen (key); ++ ++ if ((key - (char *) 0) % __alignof__ (uint64_t) != 0) ++ { ++ char *tmp = (char *) alloca (key_len + __alignof__ (uint64_t)); ++ key = copied_key = ++ memcpy (tmp + __alignof__ (uint64_t) ++ - (tmp - (char *) 0) % __alignof__ (uint64_t), ++ key, key_len); ++ } ++ ++ if ((salt - (char *) 0) % __alignof__ (uint64_t) != 0) ++ { ++ char *tmp = (char *) alloca (salt_len + __alignof__ (uint64_t)); ++ salt = copied_salt = ++ memcpy (tmp + __alignof__ (uint64_t) ++ - (tmp - (char *) 0) % __alignof__ (uint64_t), ++ salt, salt_len); ++ } ++ ++ /* Prepare for the real work. */ ++ sha512_init_ctx (&ctx); ++ ++ /* Add the key string. */ ++ sha512_process_bytes (key, key_len, &ctx); ++ ++ /* The last part is the salt string. This must be at most 16 ++ characters and it ends at the first `$' character (for ++ compatibility with existing implementations). */ ++ sha512_process_bytes (salt, salt_len, &ctx); ++ ++ ++ /* Compute alternate SHA512 sum with input KEY, SALT, and KEY. The ++ final result will be added to the first context. */ ++ sha512_init_ctx (&alt_ctx); ++ ++ /* Add key. */ ++ sha512_process_bytes (key, key_len, &alt_ctx); ++ ++ /* Add salt. */ ++ sha512_process_bytes (salt, salt_len, &alt_ctx); ++ ++ /* Add key again. */ ++ sha512_process_bytes (key, key_len, &alt_ctx); ++ ++ /* Now get result of this (64 bytes) and add it to the other ++ context. */ ++ sha512_finish_ctx (&alt_ctx, alt_result); ++ ++ /* Add for any character in the key one byte of the alternate sum. */ ++ for (cnt = key_len; cnt > 64; cnt -= 64) ++ sha512_process_bytes (alt_result, 64, &ctx); ++ sha512_process_bytes (alt_result, cnt, &ctx); ++ ++ /* Take the binary representation of the length of the key and for every ++ 1 add the alternate sum, for every 0 the key. */ ++ for (cnt = key_len; cnt > 0; cnt >>= 1) ++ if ((cnt & 1) != 0) ++ sha512_process_bytes (alt_result, 64, &ctx); ++ else ++ sha512_process_bytes (key, key_len, &ctx); ++ ++ /* Create intermediate result. */ ++ sha512_finish_ctx (&ctx, alt_result); ++ ++ /* Start computation of P byte sequence. */ ++ sha512_init_ctx (&alt_ctx); ++ ++ /* For every character in the password add the entire password. */ ++ for (cnt = 0; cnt < key_len; ++cnt) ++ sha512_process_bytes (key, key_len, &alt_ctx); ++ ++ /* Finish the digest. */ ++ sha512_finish_ctx (&alt_ctx, temp_result); ++ ++ /* Create byte sequence P. */ ++ cp = p_bytes = alloca (key_len); ++ for (cnt = key_len; cnt >= 64; cnt -= 64) ++ { ++ memcpy (cp, temp_result, 64); ++ cp += 64; ++ } ++ memcpy (cp, temp_result, cnt); ++ ++ /* Start computation of S byte sequence. */ ++ sha512_init_ctx (&alt_ctx); ++ ++ /* For every character in the password add the entire password. */ ++ for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt) ++ sha512_process_bytes (salt, salt_len, &alt_ctx); ++ ++ /* Finish the digest. */ ++ sha512_finish_ctx (&alt_ctx, temp_result); ++ ++ /* Create byte sequence S. */ ++ cp = s_bytes = alloca (salt_len); ++ for (cnt = salt_len; cnt >= 64; cnt -= 64) ++ { ++ memcpy (cp, temp_result, 64); ++ cp += 64; ++ } ++ memcpy (cp, temp_result, cnt); ++ ++ /* Repeatedly run the collected hash value through SHA512 to burn ++ CPU cycles. */ ++ for (cnt = 0; cnt < rounds; ++cnt) ++ { ++ /* New context. */ ++ sha512_init_ctx (&ctx); ++ ++ /* Add key or last result. */ ++ if ((cnt & 1) != 0) ++ sha512_process_bytes (p_bytes, key_len, &ctx); ++ else ++ sha512_process_bytes (alt_result, 64, &ctx); ++ ++ /* Add salt for numbers not divisible by 3. */ ++ if (cnt % 3 != 0) ++ sha512_process_bytes (s_bytes, salt_len, &ctx); ++ ++ /* Add key for numbers not divisible by 7. */ ++ if (cnt % 7 != 0) ++ sha512_process_bytes (p_bytes, key_len, &ctx); ++ ++ /* Add key or last result. */ ++ if ((cnt & 1) != 0) ++ sha512_process_bytes (alt_result, 64, &ctx); ++ else ++ sha512_process_bytes (p_bytes, key_len, &ctx); ++ ++ /* Create intermediate result. */ ++ sha512_finish_ctx (&ctx, alt_result); ++ } ++ ++ /* Now we can construct the result string. It consists of three ++ parts. */ ++ cp = stpncpy (buffer, sha512_salt_prefix, MAX (0, buflen)); ++ buflen -= sizeof (sha512_salt_prefix) - 1; ++ ++ if (rounds_custom) ++ { ++ char sbuf[64]; ++ sprintf (sbuf, "%s%Lu$", sha512_rounds_prefix, ++ (unsigned long long)rounds); ++ size_t n = strlen (sbuf); ++ memcpy (cp, sbuf, MIN (MAX (0, buflen), n)); ++ cp += n; ++ buflen -= n; ++ } ++ ++ cp = stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len)); ++ buflen -= MIN ((size_t) MAX (0, buflen), salt_len); ++ ++ if (buflen > 0) ++ { ++ *cp++ = '$'; ++ --buflen; ++ } ++ ++#define b64_from_24bit(B2, B1, B0, N) \ ++ do { \ ++ unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \ ++ int n = (N); \ ++ while (n-- > 0 && buflen > 0) \ ++ { \ ++ *cp++ = b64t[w & 0x3f]; \ ++ --buflen; \ ++ w >>= 6; \ ++ } \ ++ } while (0) ++ ++ b64_from_24bit (alt_result[0], alt_result[21], alt_result[42], 4); ++ b64_from_24bit (alt_result[22], alt_result[43], alt_result[1], 4); ++ b64_from_24bit (alt_result[44], alt_result[2], alt_result[23], 4); ++ b64_from_24bit (alt_result[3], alt_result[24], alt_result[45], 4); ++ b64_from_24bit (alt_result[25], alt_result[46], alt_result[4], 4); ++ b64_from_24bit (alt_result[47], alt_result[5], alt_result[26], 4); ++ b64_from_24bit (alt_result[6], alt_result[27], alt_result[48], 4); ++ b64_from_24bit (alt_result[28], alt_result[49], alt_result[7], 4); ++ b64_from_24bit (alt_result[50], alt_result[8], alt_result[29], 4); ++ b64_from_24bit (alt_result[9], alt_result[30], alt_result[51], 4); ++ b64_from_24bit (alt_result[31], alt_result[52], alt_result[10], 4); ++ b64_from_24bit (alt_result[53], alt_result[11], alt_result[32], 4); ++ b64_from_24bit (alt_result[12], alt_result[33], alt_result[54], 4); ++ b64_from_24bit (alt_result[34], alt_result[55], alt_result[13], 4); ++ b64_from_24bit (alt_result[56], alt_result[14], alt_result[35], 4); ++ b64_from_24bit (alt_result[15], alt_result[36], alt_result[57], 4); ++ b64_from_24bit (alt_result[37], alt_result[58], alt_result[16], 4); ++ b64_from_24bit (alt_result[59], alt_result[17], alt_result[38], 4); ++ b64_from_24bit (alt_result[18], alt_result[39], alt_result[60], 4); ++ b64_from_24bit (alt_result[40], alt_result[61], alt_result[19], 4); ++ b64_from_24bit (alt_result[62], alt_result[20], alt_result[41], 4); ++ b64_from_24bit (0, 0, alt_result[63], 2); ++ ++ if (buflen <= 0) ++ buffer = NULL; ++ else ++ *cp = '\0'; /* Terminate the string. */ ++ ++ /* Clear the buffer for the intermediate result so that people ++ attaching to processes or reading core dumps cannot get any ++ information. We do it in this way to clear correct_words[] ++ inside the SHA512 implementation as well. */ ++ sha512_init_ctx (&ctx); ++ sha512_finish_ctx (&ctx, alt_result); ++ memset (temp_result, '\0', sizeof (temp_result)); ++ memset (p_bytes, '\0', key_len); ++ memset (s_bytes, '\0', salt_len); ++ memset (&ctx, '\0', sizeof (ctx)); ++ memset (&alt_ctx, '\0', sizeof (alt_ctx)); ++ if (copied_key != NULL) ++ memset (copied_key, '\0', key_len); ++ if (copied_salt != NULL) ++ memset (copied_salt, '\0', salt_len); ++ ++ return buffer; ++} ++ ++ ++/* This entry point is equivalent to the `crypt' function in Unix ++ libcs. */ ++char * ++sha512_crypt (const char *key, const char *salt) ++{ ++ /* We don't want to have an arbitrary limit in the size of the ++ password. We can compute an upper bound for the size of the ++ result in advance and so we can prepare the buffer we pass to ++ `sha512_crypt_r'. */ ++ static char *buffer; ++ static int buflen; ++ int needed = (sizeof (sha512_salt_prefix) - 1 ++ + sizeof (sha512_rounds_prefix) + 9 + 1 ++ + strlen (salt) + 1 + 86 + 1); ++ ++ if (buflen < needed) ++ { ++ char *new_buffer = (char *) realloc (buffer, needed); ++ if (new_buffer == NULL) ++ return NULL; ++ ++ buffer = new_buffer; ++ buflen = needed; ++ } ++ ++ return sha512_crypt_r (key, salt, buffer, buflen); ++} ++ ++ ++#ifdef TEST ++static const struct ++{ ++ const char *input; ++ const char result[64]; ++} tests[] = ++ { ++ /* Test vectors from FIPS 180-2: appendix C.1. */ ++ { "abc", ++ "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31" ++ "\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a" ++ "\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd" ++ "\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f" }, ++ /* Test vectors from FIPS 180-2: appendix C.2. */ ++ { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" ++ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", ++ "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14\x3f" ++ "\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88\x90\x18" ++ "\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4\xb5\x43\x3a" ++ "\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b\x87\x4b\xe9\x09" }, ++ /* Test vectors from the NESSIE project. */ ++ { "", ++ "\xcf\x83\xe1\x35\x7e\xef\xb8\xbd\xf1\x54\x28\x50\xd6\x6d\x80\x07" ++ "\xd6\x20\xe4\x05\x0b\x57\x15\xdc\x83\xf4\xa9\x21\xd3\x6c\xe9\xce" ++ "\x47\xd0\xd1\x3c\x5d\x85\xf2\xb0\xff\x83\x18\xd2\x87\x7e\xec\x2f" ++ "\x63\xb9\x31\xbd\x47\x41\x7a\x81\xa5\x38\x32\x7a\xf9\x27\xda\x3e" }, ++ { "a", ++ "\x1f\x40\xfc\x92\xda\x24\x16\x94\x75\x09\x79\xee\x6c\xf5\x82\xf2" ++ "\xd5\xd7\xd2\x8e\x18\x33\x5d\xe0\x5a\xbc\x54\xd0\x56\x0e\x0f\x53" ++ "\x02\x86\x0c\x65\x2b\xf0\x8d\x56\x02\x52\xaa\x5e\x74\x21\x05\x46" ++ "\xf3\x69\xfb\xbb\xce\x8c\x12\xcf\xc7\x95\x7b\x26\x52\xfe\x9a\x75" }, ++ { "message digest", ++ "\x10\x7d\xbf\x38\x9d\x9e\x9f\x71\xa3\xa9\x5f\x6c\x05\x5b\x92\x51" ++ "\xbc\x52\x68\xc2\xbe\x16\xd6\xc1\x34\x92\xea\x45\xb0\x19\x9f\x33" ++ "\x09\xe1\x64\x55\xab\x1e\x96\x11\x8e\x8a\x90\x5d\x55\x97\xb7\x20" ++ "\x38\xdd\xb3\x72\xa8\x98\x26\x04\x6d\xe6\x66\x87\xbb\x42\x0e\x7c" }, ++ { "abcdefghijklmnopqrstuvwxyz", ++ "\x4d\xbf\xf8\x6c\xc2\xca\x1b\xae\x1e\x16\x46\x8a\x05\xcb\x98\x81" ++ "\xc9\x7f\x17\x53\xbc\xe3\x61\x90\x34\x89\x8f\xaa\x1a\xab\xe4\x29" ++ "\x95\x5a\x1b\xf8\xec\x48\x3d\x74\x21\xfe\x3c\x16\x46\x61\x3a\x59" ++ "\xed\x54\x41\xfb\x0f\x32\x13\x89\xf7\x7f\x48\xa8\x79\xc7\xb1\xf1" }, ++ { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", ++ "\x20\x4a\x8f\xc6\xdd\xa8\x2f\x0a\x0c\xed\x7b\xeb\x8e\x08\xa4\x16" ++ "\x57\xc1\x6e\xf4\x68\xb2\x28\xa8\x27\x9b\xe3\x31\xa7\x03\xc3\x35" ++ "\x96\xfd\x15\xc1\x3b\x1b\x07\xf9\xaa\x1d\x3b\xea\x57\x78\x9c\xa0" ++ "\x31\xad\x85\xc7\xa7\x1d\xd7\x03\x54\xec\x63\x12\x38\xca\x34\x45" }, ++ { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", ++ "\x1e\x07\xbe\x23\xc2\x6a\x86\xea\x37\xea\x81\x0c\x8e\xc7\x80\x93" ++ "\x52\x51\x5a\x97\x0e\x92\x53\xc2\x6f\x53\x6c\xfc\x7a\x99\x96\xc4" ++ "\x5c\x83\x70\x58\x3e\x0a\x78\xfa\x4a\x90\x04\x1d\x71\xa4\xce\xab" ++ "\x74\x23\xf1\x9c\x71\xb9\xd5\xa3\xe0\x12\x49\xf0\xbe\xbd\x58\x94" }, ++ { "123456789012345678901234567890123456789012345678901234567890" ++ "12345678901234567890", ++ "\x72\xec\x1e\xf1\x12\x4a\x45\xb0\x47\xe8\xb7\xc7\x5a\x93\x21\x95" ++ "\x13\x5b\xb6\x1d\xe2\x4e\xc0\xd1\x91\x40\x42\x24\x6e\x0a\xec\x3a" ++ "\x23\x54\xe0\x93\xd7\x6f\x30\x48\xb4\x56\x76\x43\x46\x90\x0c\xb1" ++ "\x30\xd2\xa4\xfd\x5d\xd1\x6a\xbb\x5e\x30\xbc\xb8\x50\xde\xe8\x43" } ++ }; ++#define ntests (sizeof (tests) / sizeof (tests[0])) ++ ++ ++static const struct ++{ ++ const char *salt; ++ const char *input; ++ const char *expected; ++} tests2[] = ++{ ++ { "$6$saltstring", "Hello world!", ++ "$6$saltstring$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu" ++ "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1" }, ++ { "$6$rounds=10000$saltstringsaltstring", "Hello world!", ++ "$6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sb" ++ "HbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v." }, ++ { "$6$rounds=5000$toolongsaltstring", "This is just a test", ++ "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQ" ++ "zQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0" }, ++ { "$6$rounds=1400$anotherlongsaltstring", ++ "a very much longer text to encrypt. This one even stretches over more" ++ "than one line.", ++ "$6$rounds=1400$anotherlongsalts$POfYwTEok97VWcjxIiSOjiykti.o/pQs.wP" ++ "vMxQ6Fm7I6IoYN3CmLs66x9t0oSwbtEW7o7UmJEiDwGqd8p4ur1" }, ++ { "$6$rounds=77777$short", ++ "we have a short salt string but not a short password", ++ "$6$rounds=77777$short$WuQyW2YR.hBNpjjRhpYD/ifIw05xdfeEyQoMxIXbkvr0g" ++ "ge1a1x3yRULJ5CCaUeOxFmtlcGZelFl5CxtgfiAc0" }, ++ { "$6$rounds=123456$asaltof16chars..", "a short string", ++ "$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwc" ++ "elCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1" }, ++ { "$6$rounds=10$roundstoolow", "the minimum number is still observed", ++ "$6$rounds=1000$roundstoolow$kUMsbe306n21p9R.FRkW3IGn.S9NPN0x50YhH1x" ++ "hLsPuWGsUSklZt58jaTfF4ZEQpyUNGc0dqbpBYYBaHHrsX." }, ++}; ++#define ntests2 (sizeof (tests2) / sizeof (tests2[0])) ++ ++ ++int ++sha512_test (void) ++{ ++ struct sha512_ctx ctx; ++ char sum[64]; ++ int result = 0; ++ int cnt, i; ++ ++ for (cnt = 0; cnt < (int) ntests; ++cnt) ++ { ++ sha512_init_ctx (&ctx); ++ sha512_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx); ++ sha512_finish_ctx (&ctx, sum); ++ if (memcmp (tests[cnt].result, sum, 64) != 0) ++ { ++ prom_printf ("test %d run %d failed\n", cnt, 1); ++ result = 1; ++ } ++ ++ sha512_init_ctx (&ctx); ++ for (i = 0; tests[cnt].input[i] != '\0'; ++i) ++ sha512_process_bytes (&tests[cnt].input[i], 1, &ctx); ++ sha512_finish_ctx (&ctx, sum); ++ if (memcmp (tests[cnt].result, sum, 64) != 0) ++ { ++ prom_printf ("test %d run %d failed\n", cnt, 2); ++ result = 1; ++ } ++ } ++ ++ /* Test vector from FIPS 180-2: appendix C.3. */ ++ char buf[1000]; ++ memset (buf, 'a', sizeof (buf)); ++ sha512_init_ctx (&ctx); ++ for (i = 0; i < 1000; ++i) ++ sha512_process_bytes (buf, sizeof (buf), &ctx); ++ sha512_finish_ctx (&ctx, sum); ++ static const char expected[64] = ++ "\xe7\x18\x48\x3d\x0c\xe7\x69\x64\x4e\x2e\x42\xc7\xbc\x15\xb4\x63" ++ "\x8e\x1f\x98\xb1\x3b\x20\x44\x28\x56\x32\xa8\x03\xaf\xa9\x73\xeb" ++ "\xde\x0f\xf2\x44\x87\x7e\xa6\x0a\x4c\xb0\x43\x2c\xe5\x77\xc3\x1b" ++ "\xeb\x00\x9c\x5c\x2c\x49\xaa\x2e\x4e\xad\xb2\x17\xad\x8c\xc0\x9b"; ++ if (memcmp (expected, sum, 64) != 0) ++ { ++ prom_printf ("test %d failed\n", cnt); ++ result = 1; ++ } ++ ++ for (cnt = 0; cnt < ntests2; ++cnt) ++ { ++ char *cp = sha512_crypt (tests2[cnt].input, tests2[cnt].salt); ++ ++ if (strcmp (cp, tests2[cnt].expected) != 0) ++ { ++ prom_printf ("test %d: expected \"%s\", got \"%s\"\n", ++ cnt, tests2[cnt].expected, cp); ++ result = 1; ++ } ++ } ++ ++ if (result == 0) ++ prom_printf ("all tests OK\n"); ++ ++ return result; ++} ++#endif +diff -urN --exclude '*~' yaboot/second/yaboot.c yaboot-1.3.14/second/yaboot.c +--- yaboot/second/yaboot.c 2010-01-12 22:39:21.670784810 +0100 ++++ yaboot-1.3.14/second/yaboot.c 2010-01-13 17:07:06.972808719 +0100 +@@ -634,13 +634,17 @@ + if (!strncmp (password, "$1$", 3)) { + if (!check_md5_password(passwdbuff, password)) + return; ++ } else ++#endif /* USE_MD5_PASSWORDS */ ++ if (!strncmp (password, "$5$", 3)) { ++ if (!strcmp (password, sha256_crypt (passwdbuff, password))) ++ return; ++ } else if (!strncmp (password, "$6$", 3)) { ++ if (!strcmp (password, sha512_crypt (passwdbuff, password))) ++ return; + } + else if (!strcmp (password, passwdbuff)) + return; +-#else /* !MD5 */ +- if (!strcmp (password, passwdbuff)) +- return; +-#endif /* USE_MD5_PASSWORDS */ + if (i < 2) { + prom_sleep(1); + prom_printf ("Incorrect password. Try again."); diff --git a/yaboot.spec b/yaboot.spec new file mode 100644 index 0000000..d963c32 --- /dev/null +++ b/yaboot.spec @@ -0,0 +1,521 @@ +Summary: Linux bootloader for Power Macintosh "New World" computers +Name: yaboot +Version: 1.3.14 +Release: 35%{?dist} +License: GPLv2+ +Group: System Environment/Base +Source: http://yaboot.ozlabs.org/releases/yaboot-%{version}.tar.gz +Source1: efika.forth + +# include various git patches that have been there +# Patches were included directly in tarball. This is not ok, because +# tarball was different then upstream. So do the changes in patch +Patch0: yaboot-1.3.14-gitpatches.patch + +Patch1: yaboot-1.3.3-man.patch +Patch2: yaboot-1.3.6-ofboot.patch +Patch3: yaboot-1.3.6-rh.patch +Patch4: yaboot-1.3.13-yabootconfig.patch +Patch6: yaboot-1.3.10-proddiscover.patch +Patch7: yaboot-1.3.10-ext3.patch +Patch8: yaboot-1.3.10-sbindir.patch +Patch9: yaboot-1.3.10-configfile.patch +Patch10: yaboot-1.3.10-parted.patch +Patch17: yaboot-1.3.13-pegasos-claim.patch +Patch18: yaboot-1.3.13-pegasos-ext2.patch +Patch21: yaboot-1.3.13-pegasos-serial.patch +Patch22: yaboot-1.3.13-allow-deep-mntpoint.patch +Patch28: yaboot-1.3.13-dontwritehome.patch +Patch30: yaboot-1.3.14-fix-bootonce-nvram.patch +Patch31: yaboot-1.3.14-bigger-max-token.patch +Patch32: yaboot-relocatable-kernel.patch +Patch33: yaboot-1.3.14-better_netboot.patch +Patch34: yaboot-1.3.14-no-birecs.patch + +# mkofboot in verbose mode returns bad value +Patch35: yaboot-1.3.14-returns.patch + +# ipv6 support +Patch36: yaboot-1.3.14-ipv6.patch + +# Do not open LINUX_NATIVE parttions with OF, as badness happens +Patch37: yaboot-1.3.14-dont_of_open_native_partitions.patch + +# Try #2 at better netboot now with DHCP parseing +Patch38: yaboot-1.3.14-better_netboot2.patch + +# When netbooting, move the kernel onto the load buffer, sure it's a hack +Patch39: yaboot-1.3.14-move_kernel.patch + +# SHA-2 support +Patch40: yaboot-sha2.patch + +# Solves the situation, when there is no netinfo packet +Patch41: yaboot-1.3.14-netinfo.patch + +# Better ISCSI boot +Patch42: yaboot-1.3.14-iscsi.patch + +# prom_getchar eats characters +Patch43: yaboot-1.3.14-prom_getchars.patch + +# Allow yaboot to allocate up to 256MB of memory +Patch44: yaboot-1.3.14-256-RMA.patch + +# 621598, better memory management +Patch45: yaboot-1.3.14-memory_management.patch + +URL: http://yaboot.ozlabs.org/ +BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) +ExclusiveArch: ppc + +# hfsutils will not be in RHEL6. +# hfsutils is needed only for non-IBM ppc machines +%if 0%{?fedora} || 0%{?rhel} < 6 +Requires: hfsutils +%endif +BuildRequires: e2fsprogs-devel + +# yaboot is bootloader. It contains ELF object, but it is not Linux or MacOS +# executable file. Yaboot is meant to be executed only by OpenFirmware. +# So debuginfo rpm is nonsense +%global debug_package %{nil} + +%description +yaboot is a bootloader for PowerPC machines which works on New World ROM +machines (Rev. A iMac and newer) and runs directly from Open Firmware, +eliminating the need for Mac OS. +yaboot can also bootload IBM pSeries machines. + +%prep +%setup -q +%patch0 -p1 -b .gitpatches +%patch1 -p0 -b .man +%patch2 -p1 -b .ofboot +%patch3 -p1 -b .rh +%patch4 -p1 -b .yabootconfig +%patch6 -p1 -b .proddisc +%patch7 -p1 -b .ext3 +%patch8 -p1 -b .sbin +%patch9 -p1 -b .config +%patch10 -p1 -b .parted +%patch17 -p1 -b .pegasos +%patch18 -p1 -b .ext2 +%patch21 -p1 -b .pegasos-serial +%patch22 -p1 -b .deepmnt +%patch28 -p1 -b .bootwrite +%patch30 -p1 -b .bootonce +%patch31 -p1 -b .maxtoken +%patch32 -p1 -b .relocatable +%patch33 -p1 -b .netboot +%patch34 -p1 -b .birecs +%patch35 -p1 -b .returns +%patch36 -p1 -b .ipv6 +%patch37 -p1 -b .partitions +%patch38 -p1 -b .netboot2 +%patch39 -p1 -b .movekernel +%patch40 -p1 -b .sha2 +%patch41 -p1 -b .netinfo +%patch42 -p1 -b .iscsi +%patch43 -p1 -b .prom_getchars +%patch44 -p1 -b .256-RMA +%patch45 -p1 -b .memory_management + +%build +iconv -f ISO88592 -t utf-8 -o doc/yaboot-howto.de.try.sgml \ + doc/yaboot-howto.de.sgml && mv -f doc/yaboot-howto.de.try.sgml \ + doc/yaboot-howto.de.sgml +make CFLAGS=-fno-strict-aliasing VERSIONEXTRA='\ (Red Hat %version-%release)' DEBUG=1 +cp -a second/yaboot{,.debug} +make clean +make CFLAGS=-fno-strict-aliasing VERSIONEXTRA='\ (Red Hat %version-%release)' + +%install +rm -rf $RPM_BUILD_ROOT +%makeinstall ROOT=$RPM_BUILD_ROOT PREFIX=%{_prefix} MANDIR=share/man SBINDIR=/sbin +rm -f $RPM_BUILD_ROOT/etc/yaboot.conf +touch $RPM_BUILD_ROOT/etc/yaboot.conf +mkdir -p $RPM_BUILD_ROOT/boot +install -m0644 %{SOURCE1} $RPM_BUILD_ROOT/boot/efika.forth +install -m0644 second/yaboot.debug $RPM_BUILD_ROOT/usr/lib/yaboot/ +rm -f $RPM_BUILD_ROOT/usr/share/doc/yaboot-1.3.14/README.man.patch +rm -f $RPM_BUILD_ROOT/usr/share/doc/yaboot-1.3.14/Makefile + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%doc COPYING README* doc/* +/boot/efika.forth +/sbin/ofpath +/sbin/ybin +/sbin/yabootconfig +/sbin/mkofboot +%dir /usr/lib/yaboot/ +/usr/lib/yaboot/addnote +/usr/lib/yaboot/ofboot +/usr/lib/yaboot/yaboot +/usr/lib/yaboot/yaboot.debug +%{_mandir}/man8/bootstrap.8.gz +%{_mandir}/man8/mkofboot.8.gz +%{_mandir}/man8/ofpath.8.gz +%{_mandir}/man8/yaboot.8.gz +%{_mandir}/man8/yabootconfig.8.gz +%{_mandir}/man8/ybin.8.gz +%{_mandir}/man5/yaboot.conf.5.gz +%ghost %config(noreplace) %{_sysconfdir}/yaboot.conf + +%changelog +* Fri Aug 06 2010 Roman Rakus - 1.3.14-35 +- Better memory management + Resolves: #621598 + +* Fri Jun 11 2010 Roman Rakus - 1.3.14-34 +- Use -fno-strict-aliasing CFLAG and mark /usr/lib/yaboot as a dir in files + section + Resolves: #599403 + +* Wed May 26 2010 Roman Rakus - 1.3.14-33 +- Allow yaboot to allocate up to 256MB of memory + Resolves: #596299 + +* Wed May 26 2010 Roman Rakus - 1.3.14-32 +- Get back #ExlusiveArch + Resolves: #593377 + +* Wed May 26 2010 Roman Rakus - 1.3.14-31 +- Allow copy&paste + Resolves: #593377 + +* Tue Mar 18 2010 Roman Rakus - 1.3.14-30 +- Better iSCSI booting + Resolves: #553748 + +* Tue Mar 16 2010 Roman Rakus - 1.3.14-29 +- Added missing yaboot-1.3.14-netinfo.patch + Resolves: #553061 + +* Tue Mar 16 2010 Roman Rakus - 1.3.14-28 +- Don't fail when there is no netinfo packet + Resolves: #553061 + +* Fri Feb 26 2010 Roman Rakus - 1.3.14-27 +- Update to include various changes from git that have been Fedora since .14 + was added. +- Don't end summary with dot. + +* Fri Jan 22 2010 Roman Rakus rrakus@redhat.com 1.3.14-26 +- SHA2 support + Resolves: #555093 + +* Tue Jan 12 2010 rrakus@redhat.com 1.3.14-25 +- Use correct upstream source tarball +- Patch changed for that source + Resolves: #554676 + +* Tue Jan 12 2010 rrakus@redhat.com 1.3.14-24 +- Fixed summary, buildroot +- Converted doc/yaboot-howto.de.sgml to utf8 +- Clear buildroot before install +- Removed README.man.patch and Makefile from doc dir +- Own /usr/lib/yaboot/ +- defattr(-,root,root,-) + Resolves: #554676 + +* Mon Nov 30 2009 Dennis Gregorovic - 1.3.14-23.1 +- Rebuilt for RHEL 6 + +* Thu Oct 29 2009 Roman Rakus - 1.3.14-23 +- When netbooting "clobber" the LOAD_BUFFER and move the kernel into it to make + room for RTAS (#530330) +- Adding better netboot support more work on (#458438) + +* Mon Oct 19 2009 Tony Breed - 1.3.14-22 +- Calling of_open() on a LINUX_NATIVE parttions seesm to work but end up with a + garbage file. Add check to of_open to skip these parttions (#526021). + +* Mon Oct 19 2009 Tony Breed - 1.3.14-21 +- Explicitly build a DEBUG=1 version of yaboot to aid in debugging + +* Mon Oct 19 2009 Tony Breed - 1.3.14-20 +- Only require hfsutils on fedora and rhel <= 5 + +* Thu Sep 09 2009 Roman Rakus - 1.3.14-19 +- Increase TFTP buffer to 32MB + +* Wed Sep 09 2009 Roman Rakus - 1.3.14-18 +- Do not require hfsutils on RHEL 6 + +* Fri Aug 14 2009 Roman Rakus - 1.3.14-17 +- ipv6 support +- don't build debuginfo package + +* Fri Aug 07 2009 Bill Nottingham - 1.3.14-16 +- fix patch file for (#515555) + +* Fri Aug 07 2009 Roman Rakus - 1.3.14-15 +- Fix bad return code in verbose mode (#515555) + +* Mon Jul 27 2009 Fedora Release Engineering - 1.3.14-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Sun Jun 07 2009 David Woodhouse - 1.3.14-13 +- Don't set up bi_recs. Especially not in the middle of the kernel text. + +* Mon Apr 06 2009 tony@bakeyournoodle.com - 1.3.14-12 +- Increase the TFTP load buffer from 20MiB to 25MiB. (#483051) + +* Fri Mar 13 2009 tony@bakeyournoodle.com - 1.3.14-11 +- Adding better netboot support (#458438) +- Allocate more buffer space for larger kernels and initrds (#472225) + +* Wed Feb 25 2009 Fedora Release Engineering - 1.3.14-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Jan 22 2009 Josh Boyer - 1.3.14-9 +- Add patch to handle relocatable kernels + +* Thu Nov 27 2008 Roman Rakus - 1.3.14-8 +- Bumped release, so preupgrade is now silent and go through + +* Fri Nov 21 2008 David Woodhouse - 1.3.14-7 +- Fix 'ybin --bootonce' (#471425) +- Fix maximum token length, to fix preupgrade (#471321) + +* Wed Nov 05 2008 Roman Rakus - 1.3.14-6 +- Changed kernel load base address + Resolves: #468492 + +* Mon Aug 11 2008 Roman Rakus - 1.3.14-5 +- Clearing in specfile +- Fixed patches for --fuzz=0 + +* Wed May 28 2008 Tom "spot" Callaway - 1.3.14-4 +- fix license tag + +* Wed Apr 16 2008 Roman Rakus - 1.3.14-3 +- Upstream 1.3.14 + +* Thu Mar 27 2008 David Woodhouse - 1.3.13-11 +- Correct off-by-one error in Amiga partition numbers + +* Thu Mar 27 2008 David Woodhouse - 1.3.13-10 +- Don't increment partition number to work around bplan firmware + brokenness when the config file was specified on the command line + +* Fri Feb 08 2008 David Cantrell - 1.3.13-9 +- Rebuild for gcc-4.3 + +* Wed Nov 28 2007 David Woodhouse - 1.3.13-8 +- Correct default config file location on Efika +- Disable new USB bindings in efika.forth for now + +* Tue Nov 27 2007 David Woodhouse - 1.3.13-7 +- Add efika.forth for fixing up Efika device-tree + +* Tue Nov 27 2007 David Woodhouse - 1.3.13-6 +- Detect broken bplan firmware and don't add ":0" to block device names + +* Tue Aug 21 2007 David Cantrell - 1.3.13-5 +- Rebuild + +* Thu Nov 16 2006 Paul Nasrat - 1.3.13-4 +- Add support for usb/firewire from Alex Kanavin (#208768) + +* Thu Nov 09 2006 Paul Nasrat - 1.3.13-3 +- Apply addnote patch (#184714) + +* Wed Aug 23 2006 Paul Nasrat - 1.3.13-2 +- Fix ybin with SELinux (#201414) + +* Mon Aug 21 2006 Paul Nasrat - 1.3.13-1 +- Fix multi disk G5 patch for all cases + +* Wed Jul 12 2006 Jesse Keating - 1.3.13-0.18.1 +- rebuild + +* Tue Feb 21 2006 Paul Nasrat - 1.3.13-0.18 +- Drop telnet console patch for now (#182180) + +* Fri Feb 10 2006 Jesse Keating - 1.3.13-0.17.1 +- bump again for double-long bug on ppc(64) + +* Thu Feb 09 2006 Paul Nasrat - 1.3.13-0.17 +- Fix ofpath for multi-disk G5 (#180182) + +* Tue Feb 07 2006 Jesse Keating - 1.3.13-0.16.2 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Wed Sep 14 2005 Jeremy Katz - 1.3.13-0.16 +- fix paths + +* Wed Sep 14 2005 Jeremy Katz - 1.3.13-0.15 +- fix build on ppc64 + +* Wed Sep 14 2005 Paul Nasrat - 1.3.13-0.14 +- New netboot patch handling device=alias: for non network case + +* Tue Sep 13 2005 David Woodhouse - 1.3.13-0.13 +- Print version-release of yaboot + +* Mon Sep 12 2005 Paul Nasrat - 1.3.13-0.12 +- reworking of netboot patch (Nathan Lynch) + +* Sat Aug 20 2005 Paul Nasrat - 1.3.13-0.11 +- drop netboot patch as mac cds fail to load yaboot.conf + +* Wed Aug 17 2005 Paul Nasrat - 1.3.13-0.10 +- No colours on unsupported consoles (eg telnet) +- Improved pSeries netbooting (Nathan Lynch) + +* Sun Aug 14 2005 David Woodhouse - 1.3.13-0.9 +- Try harder to allocate malloc region + +* Thu Aug 11 2005 David Woodhouse - 1.3.13-0.8 +- Allow mntpoint to be more than one directory into the partition + as long as magicboot and nvram are not being used. + +* Thu Aug 11 2005 David Woodhouse - 1.3.13-0.7 +- Fix error in swraid2 patch -- don't dereference NULL pointer. + +* Tue Aug 9 2005 David Woodhouse - 1.3.13-0.6 +- Fix handling of prom 'read' method, to make Pegasos serial work + +* Tue Aug 9 2005 David Woodhouse - 1.3.13-0.5 +- Fix Pegasos partition hack + +* Tue Aug 9 2005 David Woodhouse - 1.3.13-0.4 +- Make default boot after timeout work again +- Pegasos disagrees about partition numbering + +* Sat Jul 30 2005 David Woodhouse - 1.3.13-0.3 +- Accept config file path on command line +- Make ofpath work on Pegasos + +* Fri Jul 29 2005 David Woodhouse - 1.3.13-0.2 +- Workaround claim bug in Pegasos SmartFirmware +- Handle ext2 boot partition + +* Fri Jul 22 2005 Paul Nasrat - 1.3.13-0.1 +- Upstream 1.3.13 +- Add patches on yaboot-1.3.x tree +- Try dropping ppc64 initrd patch + +* Tue Mar 15 2005 Paul Nasrat - 1.3.12-9 +- GCC 4 rebuild + +* Wed Feb 02 2005 Paul Nasrat - 1.3.12-8 +- addnote support for IBM,RPA-Client-Config note (#145739) +- Patch to recognise l-lan as a network device + +* Wed Jul 28 2004 Paul Nasrat - 1.3.12-7 +- Add yaboot.conf as ghost + +* Sat Jul 10 2004 Paul Nasrat - 1.3.12-6 +- Rebuild + +* Sat Jul 10 2004 Paul Nasrat - 1.3.12-5 +- Added hfsutils requires for pmac + +* Wed Jun 23 2004 David Woodhouse - 1.3.12-4 +- Increase TFTP load buffer size to 8MiB. + +* Fri Jun 18 2004 Jeremy Katz - 1.3.12-3 +- s/Copyright/License/ +- fix build with gcc 3.4 + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Mon May 24 2004 Paul Nasrat 1.3.12-1 +- update to 1.3.12 + +* Tue Apr 20 2004 David Woodhouse 1.3.10-10 +- make yabootconfig use parted if available + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Fri Aug 22 2003 Elliot Lee 1.3.10-8 +- Build for rawhide + +* Fri Jun 20 2003 Jeremy Katz 1.3.10-7 +- allow passing configfile name to yabootconfig with -C + +* Wed Jun 18 2003 Jeremy Katz 1.3.10-6 +- don't ship (invalid) default yaboot.conf +- update to newer version of ppc64 initrd patch + +* Mon Apr 28 2003 Jeremy Katz 1.3.10-5 +- clean up how yabootconfig adds stuff, do some rediff'ing +- install ybin, etc in /sbin instead of /usr/sbin (#83229) + +* Wed Apr 23 2003 Jeremy Katz 1.3.10-4 +- make sure there's a newline at the end of yaboot.conf generated by + yabootconfig + +* Wed Apr 9 2003 Jeremy Katz 1.3.10-3 +- try to read product name from /etc/redhat-release instead of hard coding +- add patch (from silo) to allow mounting dirty fs's instead of mounting + read-write + +* Thu Apr 3 2003 Jeremy Katz 1.3.10-2 +- add patch from Peter Bergner to add support for + ppc64 initrds (warning: breaks ppc32 initrds) + +* Thu Mar 20 2003 Jeremy Katz 1.3.10-1 +- update to 1.3.10 +- fix ofboot patch to use Red Hat Linux instead of Yellow Dog Linux +- include patch from Dan Burcaw for yabootconfig so that it can be used + from the installer + +* Tue Jan 21 2003 Elliot Lee 1.3.8-1 +- Update to new version + +* Wed Dec 11 2002 Tim Powers 1.3.6-1b.2rh +- rebuild +- added ExclusiveArch + +* Wed Mar 06 2002 Dan Burcaw +- modify for YDL 2.2 + +* Fri Dec 07 2001 Dan Burcaw +- update to 1.3.6 + +* Sat Oct 06 2001 Dan Burcaw +- update to 1.3.4 + +* Sun Sep 30 2001 Dan Burcaw +- updated to yaboot 1.3.3 + +* Tue Sep 25 2001 Dan Burcaw +- add makefile patch + +* Sun Sep 23 2001 Dan Burcaw +- update to 1.3.1 +- obsoletes ybin + +* Thu Aug 08 2001 Dan Burcaw +- updated to 1.2.3 per Ben H's urgent announcement +- removed obsoleted patches + +* Tue Jan 16 2001 Hollis Blanchard +- hacked out bug preventing manual boot from yaboot prompt (may break CHRP) +- removed ybin's man pages +- moved to /usr/lib/yaboot for ybin, FHS compliance +- changed permissions to 644 (can't run yaboot under Linux) + +* Sat Nov 18 2000 Hollis Blanchard +- updated to yaboot 0.9 +- added man pages from ybin +- added sample yaboot.conf and bootscript (and README's) + +* Sun Feb 27 2000 Dan Burcaw +- modified for YDL + +* Wed Jan 18 2000 Tom Rini +- created