Commit yaboot 1.3.0.
git-archimport-id: erbenson@alaska.net--public/yaboot--devel--1.3--patch-1
--- /dev/null
+Bugs? what bugs? if you find one let me know. send to: erbenson@alaska.net
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
# tag: automatic-ChangeLog--erbenson@alaska.net--public/yaboot--devel--1.3
#
+2002-03-25 07:43:37 GMT Ethan Benson <erbenson@alaska.net> patch-1
+
+ Summary:
+ Commit yaboot 1.3.0
+ Revision:
+ yaboot--devel--1.3--patch-1
+
+ Commit yaboot 1.3.0.
+
+ new files:
+ .arch-ids/BUGS.id .arch-ids/COPYING.id .arch-ids/INSTALL.id
+ .arch-ids/Makefile.id .arch-ids/README.id
+ .arch-ids/README.man.patch.id .arch-ids/THANKS.id
+ .arch-ids/TODO.id .arch-ids/changelog.id doc/.arch-ids/=id
+ doc/.arch-ids/README.ofboot.id doc/.arch-ids/README.ofpath.id
+ doc/.arch-ids/README.rs6000.id doc/examples/.arch-ids/=id
+ doc/examples/.arch-ids/README.dualboot.chrp.id
+ doc/examples/.arch-ids/README.mbicons.id
+ doc/examples/.arch-ids/README.simpleboot.chrp.id
+ doc/examples/.arch-ids/dualboot.chrp.id
+ doc/examples/.arch-ids/large-penguin.mbicon.id
+ doc/examples/.arch-ids/simpleboot.chrp.id
+ doc/examples/.arch-ids/yaboot.conf.multi-boot.id
+ doc/examples/.arch-ids/yaboot.conf.rs6k.id etc/.arch-ids/=id
+ etc/.arch-ids/yaboot.conf.id first/.arch-ids/=id
+ first/.arch-ids/ofboot.id include/.arch-ids/=id
+ include/asm/.arch-ids/=id include/asm/.arch-ids/elf.h.id
+ include/asm/.arch-ids/ppc_asm.tmpl.id
+ include/asm/.arch-ids/processor.h.id
+ include/.arch-ids/bootinfo.h.id
+ include/.arch-ids/byteorder.h.id include/.arch-ids/cfg.h.id
+ include/.arch-ids/cmdline.h.id include/.arch-ids/ctype.h.id
+ include/et/.arch-ids/=id include/et/.arch-ids/com_err.c.id
+ include/et/.arch-ids/com_err.h.id include/ext2fs/.arch-ids/=id
+ include/ext2fs/.arch-ids/bitops.h.id
+ include/ext2fs/.arch-ids/ext2_err.h.id
+ include/ext2fs/.arch-ids/ext2_io.h.id
+ include/ext2fs/.arch-ids/ext2fs.h.id
+ include/.arch-ids/fdisk-part.h.id include/.arch-ids/file.h.id
+ include/.arch-ids/fs.h.id include/.arch-ids/gui.h.id
+ include/linux/.arch-ids/=id include/linux/.arch-ids/elf.h.id
+ include/linux/.arch-ids/ext2_fs.h.id
+ include/linux/.arch-ids/iso_fs.h.id
+ include/linux/.arch-ids/stat.h.id
+ include/linux/.arch-ids/types.h.id
+ include/.arch-ids/mac-part.h.id include/.arch-ids/md5.h.id
+ include/.arch-ids/partition.h.id include/.arch-ids/prom.h.id
+ include/reiserfs/.arch-ids/=id
+ include/reiserfs/.arch-ids/reiserfs.h.id
+ include/.arch-ids/setjm2.h.id include/.arch-ids/setjmp.h.id
+ include/.arch-ids/stdlib.h.id include/.arch-ids/string.h.id
+ include/.arch-ids/swab.h.id include/.arch-ids/types.h.id
+ include/.arch-ids/video.h.id include/.arch-ids/yaboot.h.id
+ lib/.arch-ids/=id lib/.arch-ids/ctype.c.id
+ lib/.arch-ids/libext2fs.a.id lib/.arch-ids/malloc.c.id
+ lib/.arch-ids/nosys.c.id lib/.arch-ids/string.S.id
+ lib/.arch-ids/strstr.c.id lib/.arch-ids/strtol.c.id
+ lib/.arch-ids/vsprintf.c.id man/.arch-ids/=id
+ man/.arch-ids/bootstrap.8.id man/.arch-ids/mkofboot.8.id
+ man/.arch-ids/ofpath.8.id man/.arch-ids/yaboot.8.id
+ man/.arch-ids/yaboot.conf.5.id man/.arch-ids/yabootconfig.8.id
+ man/.arch-ids/ybin.8.id .arch-ids/man.patch.id
+ second/.arch-ids/=id second/.arch-ids/cache.S.id
+ second/.arch-ids/cfg.c.id second/.arch-ids/cmdline.c.id
+ second/.arch-ids/crt0.S.id second/.arch-ids/file.c.id
+ second/.arch-ids/fs.c.id second/.arch-ids/fs_ext2.c.id
+ second/.arch-ids/fs_iso.c.id second/.arch-ids/fs_of.c.id
+ second/.arch-ids/fs_reiserfs.c.id second/gui/.arch-ids/=id
+ second/gui/.arch-ids/colormap.c.id
+ second/gui/.arch-ids/effects.c.id
+ second/gui/.arch-ids/pcx.c.id second/gui/.arch-ids/video.c.id
+ second/.arch-ids/iso_util.c.id second/.arch-ids/md5.c.id
+ second/.arch-ids/partition.c.id second/.arch-ids/prom.c.id
+ second/.arch-ids/setjmp.S.id second/.arch-ids/yaboot.c.id
+ util/.arch-ids/=id util/.arch-ids/addnote.c.id
+ util/.arch-ids/elfextract.c.id ybin/.arch-ids/=id
+ ybin/.arch-ids/mkofboot.id ybin/.arch-ids/ofpath.id
+ ybin/.arch-ids/yabootconfig.id ybin/.arch-ids/ybin.id BUGS
+ COPYING INSTALL Makefile README README.man.patch THANKS TODO
+ changelog doc/README.ofboot doc/README.ofpath
+ doc/README.rs6000 doc/examples/README.dualboot.chrp
+ doc/examples/README.mbicons
+ doc/examples/README.simpleboot.chrp doc/examples/dualboot.chrp
+ doc/examples/large-penguin.mbicon doc/examples/simpleboot.chrp
+ doc/examples/yaboot.conf.multi-boot
+ doc/examples/yaboot.conf.rs6k etc/yaboot.conf first/ofboot
+ include/asm/elf.h include/asm/ppc_asm.tmpl
+ include/asm/processor.h include/bootinfo.h include/byteorder.h
+ include/cfg.h include/cmdline.h include/ctype.h
+ include/et/com_err.c include/et/com_err.h
+ include/ext2fs/bitops.h include/ext2fs/ext2_err.h
+ include/ext2fs/ext2_io.h include/ext2fs/ext2fs.h
+ include/fdisk-part.h include/file.h include/fs.h include/gui.h
+ include/linux/elf.h include/linux/ext2_fs.h
+ include/linux/iso_fs.h include/linux/stat.h
+ include/linux/types.h include/mac-part.h include/md5.h
+ include/partition.h include/prom.h include/reiserfs/reiserfs.h
+ include/setjm2.h include/setjmp.h include/stdlib.h
+ include/string.h include/swab.h include/types.h
+ include/video.h include/yaboot.h lib/ctype.c lib/libext2fs.a
+ lib/malloc.c lib/nosys.c lib/string.S lib/strstr.c
+ lib/strtol.c lib/vsprintf.c man/bootstrap.8 man/mkofboot.8
+ man/ofpath.8 man/yaboot.8 man/yaboot.conf.5 man/yabootconfig.8
+ man/ybin.8 man.patch second/cache.S second/cfg.c
+ second/cmdline.c second/crt0.S second/file.c second/fs.c
+ second/fs_ext2.c second/fs_iso.c second/fs_of.c
+ second/fs_reiserfs.c second/gui/colormap.c
+ second/gui/effects.c second/gui/pcx.c second/gui/video.c
+ second/iso_util.c second/md5.c second/partition.c
+ second/prom.c second/setjmp.S second/yaboot.c util/addnote.c
+ util/elfextract.c ybin/mkofboot ybin/ofpath ybin/yabootconfig
+ ybin/ybin
+
+ modified files:
+ ChangeLog
+
+ new directories:
+ doc/.arch-ids doc/examples/.arch-ids etc/.arch-ids
+ first/.arch-ids include/.arch-ids include/asm/.arch-ids
+ include/et/.arch-ids include/ext2fs/.arch-ids
+ include/linux/.arch-ids include/reiserfs/.arch-ids
+ lib/.arch-ids man/.arch-ids second/.arch-ids
+ second/gui/.arch-ids util/.arch-ids ybin/.arch-ids doc
+ doc/examples etc first include include/asm include/et
+ include/ext2fs include/linux include/reiserfs lib man second
+ second/gui util ybin
+
+
+2002-03-25 03:28:42 GMT Ethan Benson <erbenson@alaska.net> base-0
+
+ Summary:
+ Create yaboot arch repo
+ Revision:
+ yaboot--devel--1.3--base-0
+
+ Create yaboot arch repo.
+
+ new files:
+ ./.arch-ids/ChangeLog.id ./ChangeLog
+
+
--- /dev/null
+
+The fastest way to install ybin and yaboot is to run `make install'.
+
+This will install the man pages in /usr/local/man by default and
+ybin/mkofboot in /usr/local/sbin. yaboot and ofboot will be
+installed in /usr/local/lib/yaboot/.
+
+you may change the install paths by setting variables ROOT, PREFIX and
+MANDIR to make. ie make ROOT=/ PREFIX=/usr MANDIR=/share/man (this is only
+intended for package maintainers.)
+
+yaboot can be installed where you like but
+/usr/local/lib/yaboot/yaboot is the first default location ybin will
+look, followed by /usr/lib/yaboot/yaboot.
+
+ybin needs hfsutils version 3.2.6 or later.
+
+The man pages should be installed in /usr/local/man/man?/. The *.8.gz
+pages should be in /usr/local/man/man8/ and the *.5.gz page should be
+in /usr/local/man/man5/.
+
+If you need to remove ybin (say if your installing a debian package or
+.rpm) you can do so by issuing the command `make deinstall'.
--- /dev/null
+## Configuration section
+
+VERSION = 1.3
+# Debug mode (verbose)
+DEBUG = 0
+ROOT =
+PREFIX = usr/local
+MANDIR = man
+GETROOT = fakeroot
+
+# Enable text colors
+CONFIG_COLOR_TEXT = y
+# Enable colormap setup
+CONFIG_SET_COLORMAP = y
+# Enable splash screen
+CONFIG_SPLASH_SCREEN = n
+# Enable md5 passwords
+USE_MD5_PASSWORDS = y
+
+# We use fixed addresses to avoid overlap when relocating
+# and other trouble with initrd
+
+# Load the bootstrap at 2Mb
+TEXTADDR = 0x200000
+# Malloc block at 3Mb -> 4Mb
+MALLOCADDR = 0x300000
+MALLOCSIZE = 0x100000
+# Load kernel at 20Mb and ramdisk just after
+KERNELADDR = 0x01400000
+
+# Set this to the prefix of your cross-compiler, if you have one.
+# Else leave it empty.
+#
+CROSS =
+
+# The flags for the target compiler.
+#
+CFLAGS = -Os -nostdinc -Wall -isystem `gcc -print-file-name=include` -fsigned-char
+CFLAGS += -DVERSION=\"${VERSION}\" #"
+CFLAGS += -DTEXTADDR=$(TEXTADDR) -DDEBUG=$(DEBUG)
+CFLAGS += -DMALLOCADDR=$(MALLOCADDR) -DMALLOCSIZE=$(MALLOCSIZE)
+CFLAGS += -DKERNELADDR=$(KERNELADDR)
+CFLAGS += -I ./include
+
+ifeq ($(CONFIG_COLOR_TEXT),y)
+CFLAGS += -DCONFIG_COLOR_TEXT
+endif
+
+ifeq ($(CONFIG_SET_COLORMAP),y)
+CFLAGS += -DCONFIG_SET_COLORMAP
+endif
+
+ifeq ($(CONFIG_SPLASH_SCREEN),y)
+CFLAGS += -DCONFIG_SPLASH_SCREEN
+endif
+
+ifeq ($(USE_MD5_PASSWORDS),y)
+CFLAGS += -DUSE_MD5_PASSWORDS
+endif
+
+# Link flags
+#
+LFLAGS = -Ttext $(TEXTADDR) -Bstatic
+
+# Libraries
+#
+LLIBS = lib/libext2fs.a
+#LLIBS = -l ext2fs
+
+# For compiling build-tools that run on the host.
+#
+HOSTCC = gcc
+HOSTCFLAGS = -I/usr/include $(CFLAGS)
+
+## End of configuration section
+
+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_reiserfs.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
+
+ifeq ($(CONFIG_SPLASH_SCREEN),y)
+OBJS += second/gui/effects.o second/gui/colormap.o second/gui/video.o second/gui/pcx.o
+endif
+
+ifeq ($(USE_MD5_PASSWORDS),y)
+OBJS += second/md5.o
+endif
+
+CC = $(CROSS)gcc
+LD = $(CROSS)ld
+AS = $(CROSS)as
+OBJCOPY = $(CROSS)objcopy
+
+all: yaboot addnote mkofboot
+
+lgcc = `$(CC) -print-libgcc-file-name`
+
+yaboot: $(OBJS)
+ $(LD) $(LFLAGS) $(OBJS) $(LLIBS) $(lgcc) -o second/$@
+ chmod -x second/yaboot
+
+addnote:
+ $(HOSTCC) $(HOSTCFLAGS) -o util/addnote util/addnote.c
+
+elfextract:
+ $(HOSTCC) $(HOSTCFLAGS) -o util/elfextract util/elfextract.c
+
+mkofboot:
+ ln -sf ybin ybin/mkofboot
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+%.o: %.S
+ $(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $<
+
+dep:
+ makedepend -Iinclude *.c lib/*.c util/*.c gui/*.c
+
+bindist: all
+ mkdir ../yaboot-binary-${VERSION}
+ ${GETROOT} make ROOT=../yaboot-binary-${VERSION} install
+ mkdir -p -m 755 ../yaboot-binary-${VERSION}/usr/local/share/doc/yaboot
+ cp -a COPYING ../yaboot-binary-${VERSION}/usr/local/share/doc/yaboot/COPYING
+ cp -a README ../yaboot-binary-${VERSION}/usr/local/share/doc/yaboot/README
+ ${GETROOT} tar -C ../yaboot-binary-${VERSION} -zcvpf ../yaboot-binary-${VERSION}.tar.gz .
+ rm -rf ../yaboot-binary-${VERSION}
+
+clean:
+ rm -f second/yaboot util/addnote util/elfextract $(OBJS)
+ find . -name '#*' | xargs rm -f
+ find . -name '.#*' | xargs rm -f
+ find . -name '*~' | xargs rm -f
+ rm -rf man.deb
+ chmod 755 ybin/ybin ybin/ofpath ybin/yabootconfig
+ chmod -R u+rwX,go=rX .
+ chmod a-w COPYING
+
+install: all
+ @strip second/yaboot
+ @strip --remove-section=.comment second/yaboot
+ @strip util/addnote
+ @strip --remove-section=.comment --remove-section=.note util/addnote
+ 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
+ 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
+ @gunzip man/*.gz
+ @[ ! -e ${ROOT}/etc/yaboot.conf ] && install -o root -g root -m 0644 etc/yaboot.conf ${ROOT}/etc/yaboot.conf
+ @echo
+ @echo "Installation successful."
+ @echo
+ @echo "An example /etc/yaboot.conf has been installed (unless /etc/yaboot.conf already existed"
+ @echo "You may either alter that file to match your system, or alternatively run yabootconfig"
+ @echo "yabootconfig will generate a simple and valid /etc/yaboot.conf for your system"
+ @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}/${PREFIX}/lib/yaboot/yaboot
+ rm -f ${ROOT}/${PREFIX}/lib/yaboot/ofboot
+ rm -f ${ROOT}/${PREFIX}/lib/yaboot/addnote
+ @rmdir ${ROOT}/${PREFIX}/lib/yaboot || true
+ rm -f ${ROOT}/${PREFIX}/${MANDIR}/man8/bootstrap.8.gz
+ rm -f ${ROOT}/${PREFIX}/${MANDIR}/man8/mkofboot.8.gz
+ rm -f ${ROOT}/${PREFIX}/${MANDIR}/man8/ofpath.8.gz
+ rm -f ${ROOT}/${PREFIX}/${MANDIR}/man8/yaboot.8.gz
+ rm -f ${ROOT}/${PREFIX}/${MANDIR}/man8/yabootconfig.8.gz
+ rm -f ${ROOT}/${PREFIX}/${MANDIR}/man8/ybin.8.gz
+ rm -f ${ROOT}/${PREFIX}/${MANDIR}/man5/yaboot.conf.5.gz
+ @if [ -L ${ROOT}/boot/yaboot -a ! -e ${ROOT}/boot/yaboot ] ; then rm -f ${ROOT}/boot/yaboot ; fi
+ @if [ -L ${ROOT}/boot/ofboot.b -a ! -e ${ROOT}/boot/ofboot.b ] ; then rm -f ${ROOT}/boot/ofboot.b ; fi
+ @echo
+ @echo "Deinstall successful."
+ @echo "${ROOT}/etc/yaboot.conf has not been removed, you may remove it yourself if you wish."
+
+uninstall: deinstall
--- /dev/null
+Yaboot -- PowerPC GNU/Linux OpenFirmware bootloader
+--------------------------------------------
+
+Please read the "COPYING" file for licence informations.
+
+ Copyright (C) 2000 Benjamin Herrenschmidt
+
+ portions based on "poof"
+
+ Copyright (C) 1999 Marius Vollmer
+
+ portions based on "quik"
+
+ Copyright (C) 1996 Paul Mackerras.
+
+ PPC64 support & Misc fixes by Peter Bergner, David Engebretsen
+
+
+--------------------------------------------
+
+Yaboot is an OpenFirmware bootloader for Open Firmware based
+machines. It is known to work on "NewWorld" class powermacs
+(iMac and all machines released after it), RS/6000, and possibly
+other OF based CHRP machines.
+"OldWorld" PowerMacs (with the old MacOS ROM buit-in) are not
+supported.
+
+ybin Written by Ethan Benson <erbenson@alaska.net>
+
+ybin (YaBoot INstaller) was created so that there could be a lilo/quik
+style bootloader installer for PowerPC based machines which require
+bootstrap partitions rather then a traditional bootblock (ie all
+`NewWorld' Macintoshes). It is designed to install yaboot, an
+OpenFirmware bootloader for GNU/Linux written by Benjamin
+Herrenschmidt. When ybin is configured correctly you can simply type
+ybin, and the bootloader and its configuration file will be
+installed/updated on the bootstrap partition without any further user
+intervention.
+
+ybin also supports IBM PowerPC hardware which requires a slightly
+different bootstrap partition setup, yaboot is directly dded to the
+partition instead of copied to a filesystem on the partition. For
+these machines add fstype=raw to your /etc/yaboot.conf. See
+examples/yaboot.conf.rs6k for an example configuration.
+
+Both ybin and mkofboot are shell scripts (compatible with ash, sh,
+bash). These are the first real scripts that I have written with any
+sort of complexity, so don't be too brutal if they are ugly and
+inefficient. ;-) Suggestions on how to do things better are welcome.
+
+ybin can update a bootstrap filesystem either on a block device or a
+ordinary file (as in a image of a filesystem.)
+
+Unless you use the usemount (or --mount) option it does not
+necessarily need to be run as root, but it probably will, unless you
+changed device permissions or are only updating an image.
+
+mkofboot is a companion script (actually a symlink to ybin) to
+initialise the bootstrap partition and then run ybin to install the
+bootloader on it. It uses the same configuration file as ybin to find
+the device to use. It will validate the configuration file before
+actually creating the filesystem. It will also confirm you want to
+continue before proceeding unless called with the -f or --force
+switch.
+
+(>= 0.18): ofpath utility now included which can usually find the
+OpenFirmware device path that corresponds with a unix device node in
+/dev/. Ybin will use this utility automatically to find the path to
+the bootstrap partition and to any defined macos/macosx partitions.
+NOTE: ofpath may not work with all SCSI cards/drivers.
+IMPORTANT: ofpath will NOT work if you boot your machine with BootX.
+
+ofpath is based on the utility `show_of_path.sh' written by Olaf
+Hering.
+
+(>= 0.20): ybin will now check for the new nvsetenv that is
+compatible with Newworld PowerMacs, and if found it will automatically
+update the boot-device variable in nvram to that of the bootstrap
+partition. This feature can be disabled by passing the --nonvram
+switch to ybin or by adding `nonvram' to /etc/yaboot.conf. This
+feature works in both the userland and `usemount' modes. In userland
+mode ybin sets the boot-device variable to <path>,\\:tbxi, for example
+if your bootstrap partition is /dev/hda2 boot-device will be set to
+hd:2,\\:tbxi, in `usemount' mode it would be set to hd:2,ofboot (or
+hd:2,yaboot if you don't have magicboot= set.)
+
+NEW (>= 0.31): The ofboot script now has configurable colors, you can
+change the foreground (text) and background colors it will use with
+the fgcolor= and bgcolor= options in yaboot.conf, see below for
+details. Yaboot 1.0 and later also supports these options.
+
+IMPORTANT: The bootstrap partition should never be mounted anywhere on
+your filesystem, ybin and mkofboot will check if it is and refuse to
+operate on it if its mounted. It is not necessary to keep anything
+but the boot loader on the bootstrap partition, yaboot will load the
+kernel from your ext2fs root partition so do not mount the bootstrap
+partition on top of /boot.
+
+ybin now fully supports command line switches, see ybin --help for
+information on these.
+
+NEW: ybin can now generate a basic yaboot.conf on the fly that you may
+customise with command line options:
+
+ --device yaboot auto configuration: sets the OF boot device
+ default: hd:
+ --partition yaboot auto configuration: sets the partition
+ number of the root partition. default: 3
+ --timeout yaboot auto configuration: sets the time yaboot
+ will wait for user input before booting default
+ image default: 20 (2 seconds)
+ --image yaboot auto configuration: sets the path to the
+ kernel image. default: /vmlinux
+ --label yaboot auto configuration: sets the image label
+ default: Linux
+ --root yaboot auto configuration: sets the root device
+ default: /dev/hda3
+
+This is experimental but appears to work ok.
+
+A much better method of generating an /etc/yaboot.conf is to run
+yabootconfig however.
+
+NOTE: You must have a secure mktemp program otherwise ybin will be
+vulnerable to race conditions. Debian's mktemp qualifies I don't know
+about the other distributions, you have been warned. The temp file is
+created in /tmp by default but ybin will respect the $TMPDIR
+environment variable.
+
+Configuration file documentation:
+
+ybin will verify the configuration file is sane and valid
+before proceeding.
+
+IMPORTANT: The configuration file format as of version 0.12 has
+changed, see below for the current format, note some options have been
+removed. as with version 0.11 ybin allows you to put spaces around the
+= eg: boot = /dev/hda3 (however this prevents spaces from being
+embedded in the options themselves) As of version 0.12 the separate
+ybin.conf file is deprecated, instead ybin's options should be placed
+in /etc/yaboot.conf, you must have yaboot 0.6 or later for this to
+work. Ybin will no longer use the obsolete /etc/ybin.conf.
+
+The kludge, and kludgedir options have been removed. The bootconf
+option has been deprecated since yaboot and ybin both use
+/etc/yaboot.conf (or whatever config file is specified to the -C
+switch).
+
+boot= (same as -b or --boot)
+
+This option defines what device the bootstrap partition is. It also
+be a regular file if you are creating a filesystem image for some
+reason. It is safe to specify a MacOS boot partition as long as you DO
+NOT use mkofboot. ybin is non destructive except that is overwrites
+any existing yaboot files (yaboot and yaboot.conf) at the root level
+of the bootstrap filesystem. The default config file has this set to
+"unconfigured which will cause ybin to complain about you not reading
+the docs, it is the only option you should need to change for ybin to
+work. Example boot=/dev/hda2
+
+ofboot= (same as -o or --ofboot)
+
+This option defines the OpenFirmware device path to the bootstrap
+partition. This is needed so the first stage ofboot loader can be
+configured properly. It should include the OpenFirmware path
+including the partition number (but not a filename). Example: if your
+bootstrap partition is /dev/hda2 the OF path will likely be hd:2.
+As of ybin 0.18 you no longer are required to specify this option, if
+left undefined ybin will attempt to figure out the OpenFirmware path
+automatically using the ofpath utility. You should only need to
+define this option if ofpath fails.
+
+install= (same as -i or --install)
+
+The full pathname to the yaboot OpenFirmware executable file. This
+file will be copied to the root level of the bootstrap partition, its
+filename will not be changed. The default is
+/usr/local/lib/yaboot/yaboot, or if that does not exist
+/usr/lib/yaboot/yaboot.
+
+magicboot= (same as -m or --magicboot)
+
+The full pathname to any OF CHRP script file. If this is defined then
+it will be given the HFS filetype defined below and the bootfile will
+be given type "boot" instead, if we set two files to `tbxi' we may get
+unpredictable results from OF. A wrapper file would generally only be
+needed if you have a OF script that creates a nice boot menu or
+possibly adds a option to the newer ibook boot screens. IMPORTANT: it
+appears that OF will only load `tbxi' files if they have a CHRP script
+embedded, so this option is now on by default and will install the
+included basic script that just loads the yaboot executable. (at least
+until/if yaboot gets a embedded script) If you later change your mind
+about using an OF wrapper you will have to delete it manually from the
+bootstrap partition, ybin will not and cannot do it for you. If the
+partition is a dedicated bootstrap partition you can run mkofboot to
+remove it (and anything else). This should be set to
+/usr/local/lib/yaboot/ofboot which is the new first stage loader
+configured automatically by ybin from options in /etc/yaboot.conf.
+
+bsd=
+
+The OpenFirmware or unix device path to a NetBSD or OpenBSD bootstrap
+partition, this partition must already have the BSD ofwboot.elf
+bootloader installed in the root directory. 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
+/usr/local/lib/yaboot/ofboot script. When this is set to a unix
+device node (ie /dev/hda11) then ybin will use the ofpath utility to
+determine the OpenFirmware device path.
+
+macos=
+
+The OpenFirmware or unix device path to a MacOS 8.* or 9.* boot
+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 /usr/local/lib/yaboot/ofboot script.
+When this is set to a unix device node (ie /dev/hda11) then ybin will
+use the ofpath utility to determine the OpenFirmware device path.
+
+macosx=
+
+The OpenFirmware or unix device path to a MacOS X boot 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 X to boot MacOSX
+(along with other choices if configured). This will only work if you
+are using the new /usr/local/lib/yaboot/ofboot script.
+When this is set to a unix device node (ie /dev/hda11) then ybin will
+use the ofpath utility to determine the OpenFirmware device path.
+
+brokenosx
+
+This option causes the menu entry for MacOSX to execute
+\System\Library\CoreServices\BootX from the macosx=device instead of
+the usual \\:tbxi. This is necessary if OSX is installed onto an HFS+
+filesystem instead of UFS. When OSX is installed on an HFS+ filesystem
+MacOS will mount and debless the OSX partition. Add this option if
+the OSX menu entry breaks after booting MacOS. You should not use
+this option if OSX is installed on a UFS filesystem, for UFS installs
+you specify the OSX bootstrap partition which is protected against
+MacOS.
+
+darwin=
+
+The OpenFirmware or unix device path to a Darwin boot 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 D to boot Darwin
+(along with other choices if configured). This will only work if you
+are using the new /usr/local/lib/yaboot/ofboot script. When this is
+set to a unix device node (ie /dev/hda11) then ybin will use the
+ofpath utility to determine the OpenFirmware device path.
+
+enablecdboot
+
+This option adds an entry to the multiboot menu to boot from the CDROM
+drive.
+
+enablenetboot
+
+This option adds an entry to the mulitboot menu to boot from the
+network.
+
+enableofboot
+
+This option adds an entry to the multiboot menu to boot into an
+OpenFirmware prompt.
+
+defaultos=
+
+The name of the default OS to load. This can be linux, bsd, macos or
+macosx. This option controls what the first stage ofboot loader will
+boot by default after the delay elapses. This is only relevant if you
+are using the new /usr/local/lib/yaboot/ofboot script and you have
+defined bsd= and/or macos= and/or macosx= in /etc/yaboot.conf.
+
+delay=
+
+The time in seconds that the first stage ofboot loader will wait for
+you to choose L for GNU/Linux,M for MacOS, or X for MacOSX before
+booting the default OS defined in defaultos=. If not set the value of
+timeout= (converted to seconds) will be used.
+
+usemount (same as -M or --mount)
+
+Whether or not to use the standard mount and umount utilities (and
+thus kernel space filesystem drivers instead of userspace utilities
+that manipulate the partition directly (through the device file). If
+this option is present ybin will insist that you be root. Note that
+using this option will prevent ybin from setting HFS attributes on the
+boot files (such as type and creator). This option is here mainly to
+allow ybin's use even if you do not have hfsutils. Default: no
+IMPORTANT: It is not possible to bless the filesystem when mounted
+this way, you will thus have to manually configure OF to make your
+system bootable.
+
+mntpoint=
+
+Requires `usemount' this works exactly like usemount does except it
+does not mount the bootstrap partition but rather installs the
+bootloader into the directory defined as the mountpoint. The pathname
+MUST be clean, ie no embedded spaces or metacharacters. The directory
+may not be more then one subdirectory deep from the root of the
+partition (not necessarily the unix /). You must not have a trailing
+/ either. This option is NOT recommended since it has the same
+limitations as usemount, your system will not be bootable by
+OpenFirmware, it will only be manually bootable or bootable if you
+change the boot-device variable to the direct pathname to the
+bootloader (which ybin will attempt to do).
+
+fstype= (same as --filesystem)
+
+This defines what kind of filesystem exists (or created by mkofboot)
+on the bootstrap partition. Possible options are hfs and msdos (if
+anyone can figure out how to get OF to execute a file on a ISO
+filesystem I will add that too) Note that if you use msdos filesystem
+you must have a DOS style partition table and not a Apple partition
+map. (it also requires that usemount be yes) yaboot may not yet
+support this configuration. The "raw" type causes ybin or mkofboot to
+copy the bootloader (value of install=) to the bootstrap without any
+filesystem. CAUTION: this will destroy any data or filesystem on the
+bootstrap partition (value of boot=) if you specify something like
+boot=/dev/sda you will destroy the partition table and lose ALL data
+on the disk. Default: hfs
+
+hfstype=
+
+This defines the 4 character code that should be given to the bootfile
+(the bootconf file will always be given type "conf") The main purpose
+of this is to make OF think its loading a MacOSROM image file and boot
+the system into GNU/Linux from the bootstrap partition as
+automatically as it would MacOS. In order for this to work you should
+set this to `tbxi' (the default in the included config file). If you
+have specified a OF wrapper (see above) then it will be given this
+filetype and the bootfile will be given type "boot" instead. NOTE:
+This appears to not work unless the bootfile has a CHRP boot script
+embedded in the header, at the moment yaboot lacks this script, see
+README.ofboot for more details. Default: tbxi
+
+hfscreator=
+
+This defines the 4 character creator code that should be given to both
+the bootfile and the bootconf files. This is largely pointless but if
+you use MacOS you could configure it so you have a pretty icon on the
+bootloader files. Default: UNIX
+
+nobless (same as --nobless)
+
+This prevents ybin from "blessing" the root directory of the bootstrap
+partition. This is Macspeak for "bootable directory" on the MacOS the
+System Folder is "blessed". Blessing the root directory will allow OF
+to find the bootstrap partition and load the bootloader automatically
+without reconfiguration (assuming the bootstrap partition is on the
+default disk (internal IDE in most cases). You should probably only
+set this if you are keeping the bootloader on a MacOS boot partition.
+
+protect (same as --protect)
+
+This defines whether the read-only bit should be set on the boot
+files, this is mostly pointless but slightly discourages
+tampering/deleting of the bootloader files if the bootstrap partition
+is mounted by MacOS. (hide below really would do a better job of
+that) This option will work with both msdos and hfs filesystems. It
+also works whether you have the usemount option set or not.
+
+hide (same as --hide)
+
+This defines whether or not the HFS invisible bit should be set on the
+boot files. This is a stronger way to make sure nobody fscks up your
+bootloader on the MacOS side of things. (A better option is a
+dedicated bootstrap partition with its partition type set to
+Apple_Bootstrap which is acceptable to OF but MacOS will refuse to mount
+it.) This option is ignored for msdos filesystems and will only work
+if usemount is not set.
+
+nonvram (same as --nonvram)
+
+This option prevents ybin from using nvsetenv to set the OpenFirmware
+boot-device variable in nvram. This is currently required for IBM
+machines. NOTE: you should not use this option when dual booting
+MacOS, it will cause the MacOS boot menu entries to fail on some
+machines.
+
+fgcolor=string
+
+Specifies the foreground (text) color used by yaboot(8) and the
+multiboot menu. Available colors are: black, blue, light-blue, green,
+light-green, cyan, light-cyan, red, light-red, purple, light- purple,
+brown, light-gray, dark-gray, yellow, and white. The default is
+white.
+
+bgcolor=string
+
+Specifies the background color used by yaboot(8) and the mulitboot
+menu. Available colors are: black, blue, light-blue, green,
+light-green, cyan, light-cyan, red, light-red, purple, light-purple,
+brown, light-gray, dark-gray, yellow, and white. The default is
+black.
+
+ybin does not make any validations of the yaboot specific options,
+that is up to you to make sure yaboot is configured correctly.
+
+===========================================================================
+
+Copyright (C) 2001 Ethan Benson
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+===========================================================================
--- /dev/null
+This patch is only meant to be used by package maintainers (debian or
+redhat), it changes references to /usr/local/lib/yaboot to
+/usr/lib/yaboot in the man pages. This way the man pages will better
+reflect the real locations for packaged version of yaboot/ybin.
--- /dev/null
+In no particular order:
+
+ * Daniel Jacobowitz <dan@debian.org> for Debian packaging, advice and busybox help.
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org> for yaboot and great work on the kernel.
+ * Charles Stevenson <csteven@newhope.terraplex.com> for adding color config support to yaboot.
+ * Chris Emerson <cemerson@chiark.greenend.org.uk> for the Forth code in ofboot.
+ * iNOUE Koich! <inoue@ma.ns.musashi-tech.ac.jp> for advice and help [re]writing ofboot's Forth code.
+ * Segher Boessenkool <segher@chello.nl> for help with ofboot's Forth code, and the new penguin icon.
+ * Tom Rini <trini@kernel.crashing.org> for adding devfs support to ofpath.
+ * Eric Peden <ericpeden@homemail.com> for writing the yaboot FAQ.
+ * Nicholas Humfrey <njh399@ecs.soton.ac.uk> for the badge icons in ofboot.
+ * Hollis Blanchard <hollis+@andrew.cmu.edu> YellowDog/RPM packaging.
+ * Brad Midgley <brad@turbolinux.com> for Turbolinux/RPM packaging.
+ * Olaf Hering <olh@suse.de> for figuring out how to map SCSI /dev nodes to OF paths.
+ * Josh Huber <huber@mclinux.com> for PowerBook1998 ofpath support.
+ * Ian the T <ian@iantheterrible.com> for donating shell access to add 8600 support to ofpath.
+ * anyone i left out!
--- /dev/null
+
+* Add nvram updating support for IBM hardware. This requires ofpath
+ to support these machines. It also requires a compatible nvsetenv
+ or equivilent.
+
+* Validate yaboot options before proceeding. (need better config parsing)
+
+* Password protection for insecure menu options (MacOS).
+
+* Figure out all the crap with CHRP netbooting, probably have to remove
+ hard-coding of ":0" after a net devuce path
+
+* Support for compressed images
--- /dev/null
+2001-09-20 Ethan Benson <erbenson@alaska.net>
+
+ * Version 1.3
+
+ * Merging of ybin and yaboot source trees, this is now the
+ official upstream yaboot/ybin source tree.
+
+ * yaboot:
+ - Various ppc64 & chrp fixes by Peter Bergner, fix fdisk partition
+ handling.
+ - Fix netboot (was broken by reiserfs patch)
+
+2001-08-26 Ethan Benson <erbenson@alaska.net>
+
+ * Version 1.2.6
+
+ * ofpath became broken on non-scsi systems due to quoting fix.
+
+2001-08-20 Ethan Benson <erbenson@alaska.net>
+
+ * Version 1.2.5
+
+ * Fix broken quoting uncovered by debian's current /bin/ash.
+
+2001-08-06 Ethan Benson <erbenson@alaska.net>
+
+ * Version 1.2.4
+
+ * ofboot: remove <OS-VOLUME-NAME> tag as it was causing the
+ OpenFirmware multibooter to crash.
+
+ * mkofboot: zero first 800K of bootstrap partition before creating
+ filesystem.
+
+ * yaboot:
+ - Version 1.2.3
+ - Supports using an md5 hash as well as plaintext password. (me)
+ - Fix again system.map loading. That also fix an old pending bug
+ we had where yaboot could pass random values for system.map,
+ causing the kernel to mark random pages reserved. (BenH)
+ - IBM CHRP fixes. (Peter Bergner)
+ - Add reiserfs support (Jeff Mahoney)
+
+2001-06-30 Ethan Benson <erbenson@alaska.net>
+
+ * Version 1.2.3
+
+ * ofpath:
+ - Version 1.0
+ - Add support for IBM CHRP, thanks to Marco d'Itri for testing.
+ - Use real wc if available, this speeds up ofpath slightly for scsi.
+ - Make variables local to their function unless they need to be global.
+
+ * ybin:
+ - If installing on IBM CHRP run addnote on yaboot binary before installing.
+ - Reword some error/verbose messages
+ - Make variables local to their function unless they need to be global.
+
+2001-06-24 Ethan Benson <erbenson@alaska.net>
+
+ * Version 1.2.2
+
+ * yabootconfig:
+ - Now works with braindamaged versions of pdisk.
+ - Add --kernel-args switch which allows boot-floppies to easily
+ add an append= line if needed.
+
+2001-06-01 Ethan Benson <erbenson@alaska.net>
+
+ * Version 1.2.1
+
+ * Fix test for strict posix/SUS echo behavior.
+
+ * Check for printf built into the shell.
+
+ * yabootconfig: check for and attempt to deal with cross device symlinks.
+
+2001-05-28 Ethan Benson <erbenson@alaska.net>
+
+ * Version 1.2
+
+ * Added yabootconfig, a script to build a valid /etc/yaboot.conf
+
+ * ybin:
+ - Detect IBM CHRP hardware and disable nvram update automatically
+ - Automatically run yabootconfig if /etc/yaboot.conf is missing
+ - Check for PATH_PREFIX environment variable and add all bin and
+ sbin directories from under it to PATH. This is for boot-floppies.
+ - Add bsd= to list of multiboot options.
+
+ * ofboot: bump maximum number of OSes to 8.
+
+ * ofpath:
+ - No longer report bogus paths for non-existent scsi devices.
+ - Fix bug where garbage characters were mixed with the
+ OpenFirmware device path.
+ - Fix broken Wallstreet PowerBook support.
+ - Add support for silly devfs naming convention, Thanks to Tom Rini.
+
+2001-05-06 Ethan Benson <erbenson@alaska.net>
+
+ * Version 1.1.1
+
+ * ofboot:
+ - Hopefully fix random and rare booting problem when chainloading
+ other OSes. Thanks to Segher Boessenkool for the fix.
+ - Add volume name which shows up in the OpenFirmware multiboot
+ screen.
+ - It is now possible to replace the badge icon for the multiboot
+ screen, see examples/README.mbicon.
+
+ * yaboot:
+ - Version 1.2.1
+ - Includes my previous 1.1.1-eb3 patches for password protection and single-key.
+
+ * Various spelling errors and clarifications to man pages. Thanks to sword.
+
+2001-04-26 Ethan Benson <erbenson@alaska.net>
+
+ * Version 1.1
+
+ * ofpath:
+ - Version 0.8
+ - Add support for Performa 6400_200, PowerMac 4400, and the clones.
+ - Removed `No such file or directory' errors when system has no
+ scsi at all.
+
+ * ybin:
+ - If delay= is not set use value of timeout= (converted to
+ seconds) instead.
+ - Removed command line options --type, --creator, and long
+ obsolete and deprecated --conffile. The config file options
+ hfstype and hfscreator are still there.
+ - Removed long obsolete and deprecated bootconf= config option.
+ - Removed some old now unneeded debug cruft.
+
+ * yaboot:
+ - Include version 1.1.1-eb3, this includes the following changes
+ - Adds password protection capabilities.
+ - Add `single-key' option from silo.
+
+ * Documentation:
+ - Rewrote the yaboot.conf man page, now derived from silo.conf(5)
+
+2001-03-22 Ethan Benson <erbenson@alaska.net>
+
+ * Version 1.0
+
+ * ybin:
+ - Fix a few bugs that occured when magicboot= was not used.
+ - Add basic support for IBM style bootstrap partitions. These
+ partitions have yaboot dded directly to them. See the yaboot.conf
+ man page regarding fstype for more info, also
+ examples/yaboot.conf.rs6k.
+ - Don't require that ofpath be installed if its not needed.
+
+ * Documentation:
+ - Added examples/yaboot.conf.rs6k
+ - Man page updates for IBM support.
+
+2001-02-19 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.31
+
+ * ofpath:
+ - Quiet shell error when run on non-PowerMac (but still
+ PowerPC) hardware.
+ - Properly recognize more OldWorld PowerMac G3s.
+ - Fix OldWorld detection for kernels < 2.2.17
+ - Require that /proc be mounted.
+
+ * ybin:
+ - Fix OldWorld detection for kernels < 2.2.17
+ - Make the `not bootable on OldWorld' warning very loud and
+ obnoxious.
+ - Change PATH to make /usr/local the last component instead of
+ the first.
+ - Make the text/background color in the boot menu configurable,
+ see the yaboot.conf(5) man page for details.
+ - Change default foreground color to white per yaboot 1.0.
+ - Remove support for obsolete /etc/ybin.conf.
+
+ * Documentation:
+ - Clarified the `partition=' variable in the yaboot.conf man page
+ and correct an error in the example in that man page.
+ - Added more comments to included yaboot.conf examples.
+
+ * yaboot:
+ - Include version 1.1.1
+ - Includes color support
+
+2000-11-18 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.30
+
+ * ybin: add `brokenosx' option, when used with macosx= ybin makes
+ the MacOSX menu entry execute \System\Library\CoreServices\BootX
+ directly instead of using \\:tbxi. This is necessary for
+ people who insist on installing OSX on HFS+ instead of UFS, since
+ MacOS deblesses HFS+ OSX partitions.
+
+2000-10-28 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.29 (the brown paper bag release)
+
+ * The yaboot.conf man page was broken.
+
+ * While were at it, include yaboot 0.9 binary (compiled -Os,
+ stripped)
+
+2000-10-24 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.28
+
+ * ybin: Add mntpoint= option, this allows ybin to install the
+ bootstrap into an already mounted filesystem. This is NOT
+ recommended unless you know what your doing.
+
+ * ybin: fixed generation of ofboot.b so it will work with nobless
+ and usemount.
+
+2000-10-20 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.27
+
+ * ofboot: fixed problem where text was not visible on some newer iMacs.
+
+ * ybin: Now warn the user when they are using ybin on an OldWorld
+ PowerMac. (it will still work since its possible to make newworld
+ bootable disks on an OldWorld mac)
+
+ * ofpath: Now works on oldworld macs under 2.4 kernels.
+
+ * Added check for packaged versions of ybin to the Makefile and
+ warn user about them.
+
+2000-09-23 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.26
+
+ * ofboot: completely rewrote the generator script, it is now more
+ extendable and supports more menu options. More thanks to iNOUE
+ Koich! for the continuing help on OpenFirmware issues!!
+
+ * ybin: added options for mulitboot menu: now can create a menu
+ with options for GNU/Linux, MacOS, MacOSX, Darwin, and booting off
+ a CDROM, from the network, and even directly into an OpenFirmware
+ prompt.
+
+ * ybin: some errors were sent to stdout instead of stderr, fixed.
+
+ * ofpath: refuse to run on anything but GNU/Linux. (for now anyway)
+
+2000-09-18 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.25
+
+ * ofboot: now changes the background color to black and the text
+ color to cyan like yaboot. Thanks to again to iNOUE Koich!
+
+2000-09-16 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.24
+
+ * ofboot: many bugs in the Forth code fixed. code should now be
+ compliant to the OpenFirmware spec. Also add CD boot menu option.
+ (add enablecdboot to /etc/yaboot.conf) Thanks to iNOUE Koich! for
+ the Forth code.
+
+2000-09-13 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.23
+
+ * ybin: now hard code the target filename for ofboot, its always
+ installed as ofboot.b on the bootstrap partition. This eliminates
+ ambiguity when someone tries a different script with different name.
+
+ * ybin: all debugging output goes to stderr now.
+
+2000-09-09 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.22
+
+ * ofboot.b renamed to ofboot. (.b means boot block which this is not)
+
+ * yaboot and ofboot are now installed in /usr/local/lib/yaboot/
+ instead of /boot, since these files are never directly accessed by
+ the firmware it is not really appropriate to keep them in /boot.
+ make install will create backwords compatibility symlinks when
+ installing over an older version of ybin so nothing should break.
+ IMPORTANT: you should run mkofboot on a dedicated bootstrap
+ partition to purge old filenames.
+
+ * Man pages updated to reflect new file locations. Also include a
+ patch to change the paths to /usr/lib/yaboot for Debian and redhat
+ package maintainers.
+
+ * ybin: now checks two places for a default value for install=
+ /usr/local/lib/yaboot/yaboot, /usr/lib/yaboot/yaboot.
+
+2000-09-02 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.21
+
+ * ybin: fixed nvram update so it uses a real filename instead of
+ \\:tbxi when nobless is set in /etc/yaboot.conf. (\\: means find
+ file in blessed directory).
+
+ * ofpath: more oldworld machines supported. Now supports 7200,
+ 7300, 8600, 9500, Gossamer G3, PowerBook 1998, PowerBook 3400 (and
+ possibly 2400).
+
+2000-08-31 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.20
+
+ * ybin: check for Newworld compatible nvsetenv and if found will
+ automatically update the OpenFirmware boot-device variable in
+ nvram.
+
+ * ofpath: support some oldworld machines. (this does not mean
+ ybin/yaboot supports oldworld). Also silence a harmless error on
+ machines lacking a CDROM.
+
+ * ofboot.b: added more machines to <COMPATIBLE>
+
+2000-08-25 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.19
+
+ * Added PowerMac3,2 and PowerMac3,3 to ofboot.b scripts. Fixes
+ Debian bug #69870
+
+2000-08-22 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.18
+
+ * ofboot.b: changed the yaboot boot commands to boot yaboot by
+ filename rather then file type. Booting by file type did not work
+ reliably on all machines.
+
+ * ybin: hard code the target filename for yaboot, regardless of
+ the source filename (from install=) the target filename on the
+ bootstrap partition will always be "yaboot.b".
+
+ * Added ofpath utility, this is a rewrite of the show_of_path.sh
+ utility written by Olaf Hering. Ofpath works with /bin/ash and on
+ stripped down systems such as the Debian boot floppies. Also
+ wrote a small man page for this utility.
+
+ * ybin: automatically use ofpath to find the OpenFirmware device
+ path when ofpath= is not defined in /etc/yaboot.conf. Ybin will
+ also use ofpath when macos= or macosx= are set to unix device
+ nodes (ie /dev/hda11), these options can still be set to
+ OpenFirmware paths as well.
+
+ * Makefile: minor cleanup, added installation of ofpath
+ utility/man page as well as a deinstall rule.
+
+2000-08-13 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.17
+
+ * Yaboot 0.7 binary included.
+
+ * ybin: fix bug where ybin would fail if the bootstrap files
+ included an "_" in the filename. (actually its a workaround for
+ hfsutils brain-damage)
+
+ * ofboot.b: completely rewritten. Now includes shell script code
+ to allow ybin to configure it based on config options in
+ /etc/yaboot.conf instead of requiring the user to edit it
+ themselves. Additionally this new script will display a REAL boot
+ menu when dual booting is configured. It is capable of dual or
+ tri booting GNU/Linux (yaboot), MacOS 8.*/9.* and MacOSX. This
+ new ofboot.b script should *NOT* be edited by the user, and thus
+ should NOT be marked as a conffile in Debian and redhat packages.
+ These packages should now install ofboot.b in /boot instead of
+ /etc since it is no longer a config file. WARNING: The Forth code
+ in this script has not been tested on all machines and may not be
+ universally compatible. Thanks to Chris Emerson for writing the
+ Forth code.
+
+ * yaboot.conf: new options: ofboot= macos= macosx= delay=
+ defaultos=. See the yaboot.conf man page for details.
+
+ * Now include a Makefile to handle installation, only make install
+ is defined. Removed install-sh.
+
+ * mkofboot is now distributed and installed as a symlink instead
+ of a hardlink.
+
+ * Man page updates.
+
+2000-04-25 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.16
+
+ * menu_ofboot.b: fixed bug where the yaboot line was missing the
+ boot command, this prevented it from booting yaboot.
+
+2000-04-25 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.15
+
+ * Merge quik's bootstrap(8) man page with ybin's ofboot(8) man
+ page and rename it back to bootstrap(8). This also solves the
+ conflict with quik. In a more useful way IMO.
+
+2000-04-24 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.14
+
+ * Ship man pages uncompressed, gzip them in install-sh instead,
+ this allows for easier patching by debian maintainers if need be.
+
+ * Rename bootstrap(8) man page to ofboot(8) so ybin does not
+ conflict with quik.
+
+2000-04-23 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.13
+
+ * Rewrote the config file parsing yet again to remove dependencies
+ on tr, and awk. This allows ybin to function on minimal systems
+ such as boot/rescue floppies. This also pretty much solves the
+ slowness problem. Thanks to Daniel Jacobwitz for the help.
+
+ * Made changes to remove dependencies on basename and wc. Again
+ this is to allow ybin to work on boot floppies.
+
+ * Changed all calls to grep to stop using GNU extensions, this is
+ so ybin will work properly with the minimal version of grep
+ included in busybox.
+
+ * Added signal handling so ybin/mkofboot will cleanup after
+ themselves if killed with signals 1 2 3 or 15.
+
+ * Added OS Badge icons to the ofboot.b scripts. On G4 machines
+ you can hold down the option key and get a graphical boot selector
+ with one button for each bootable partition, the button with the
+ penguin icon is the bootstrap partition. Thanks to Nicholas
+ Humfrey for creating the Badge icon.
+
+ * Minor updates to the man pages.
+
+2000-04-19 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.12
+
+ * Now include yaboot binary in ybin distribution.
+
+ * Include a install-sh script to install everything.
+
+ * Use of the separate ybin.conf file is deprecated. Use
+ /etc/yaboot.conf instead.
+
+ * Removed the so called kludge options, without being able to
+ bless the root directory they were just useless bloat.
+
+ * Removed useless --readonly option, it was already default (as it
+ should be)
+
+ * Deprecated bootconf options since the yaboot.conf is the same
+ config ybin uses. (it is still there and works but that may change)
+
+ * Changed configuration file format to be more like quik/lilo:
+ bootfile= is now install= (--bootfile is now --install), wrapper=
+ is now magicboot=, usemount, protect, and hide are now just a
+ keyword options, if they are present in the configuration file
+ they are turned on, if they are not present they are turned off.
+ bless= is now the nobless keyword option, since bless is default
+ this one changed names.
+
+ * ybin: no longer need to specify -C /dev/null if you don't have a
+ configuration file in /etc/. If this is the case ybin will generate
+ a generic yaboot.conf to install on the bootstrap partition.
+
+ * More changes to the configuration parsing to improve speed, the
+ format change also helped the speed problem.
+
+ * Added man pages for ybin, mkofboot, yaboot, yaboot.conf and
+ bootstrap.
+
+ * More general fixes/cleanup/tweaks.
+
+2000-03-13 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.11
+
+ * Added command line options to both scripts, try --help. This
+ makes the ybin.conf file optional if you wish (-C /dev/null)
+
+ * Changed the way the config file is parsed, no longer source it
+ with the shell, this allows ybin.conf to be merged with
+ yaboot.conf at which point yaboot can live with unknown options in
+ its config file.
+
+ * Use /etc/ybin.conf if it exists, if not use /etc/yaboot.conf for
+ ybin configuration.
+
+ * Merged ybin and mkofboot into one script, mkofboot shared 90% of
+ of its code with ybin anyway and this will make them much easier
+ to maintain. mkofboot is now a hard link to ybin (or a symlink if
+ you prefer, both will work)
+
+ * Added an experimental feature to generate a yaboot.conf on the
+ fly based on command line options. The defaults should be
+ workable on a Debian system with an internal ATA disk, with the
+ root partition being the 3rd on the disk. Depends on mktemp for
+ creating the temporary file, Debian's mktemp is secure against
+ race conditions, use with caution if your distribution lacks a
+ secure mktemp utility. This option is activated with -c auto.
+
+ * No longer depends on bash. Works with Debian's
+ /bin/ash. Interpreter is now set to /bin/sh.
+
+ * Assorted cleanup, minor bug fixes.
+
+ * Added example yaboot.conf.
+
+2000-02-04 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.10
+
+ * Added a simple multi-boot menu written by Benjamin Herrenschmidt.
+
+2000-01-17 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.9
+
+ * mkofboot was still broken. :-(
+
+
+2000-01-14 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.8
+
+ * Added a basic CHRP script ofboot.b to work around the problem of
+ OF refusing to load `tbxi' files unless they contain a CHRP boot
+ header. See README.ofboot.b for details.
+
+ * Updated default ybin.conf to install ofboot.b by default.
+
+2000-01-13 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.7
+
+ * mkofboot: Check for hformat was broken.
+
+2000-01-12 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.6
+
+ * mkofboot: Fixed problem where it was insisting that mkdosfs be
+ present even when using hfs filesystems if usemount=yes.
+
+ * mkofboot: Added proper checks for hformat or mkdosfs.
+
+2000-01-09 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.5
+
+ * First public release.
+
+ * Add TODO and BUGS files.
+
+ * mkofboot: Check to see if usemount=yes, and if so make sure we
+ are root before proceeding to erase the partition.
+
+ * ybin: Removed useless echo line.
+
+2000-01-05 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.4
+
+ * ybin (util_install): Fully support OF `wrappers' now: if a
+ wrapper is defined in the configuration file then the wrapper is
+ given the HFS file type specified instead of the bootfile, the
+ bootfile's type is set to "boot".
+
+ * ybin: New configuration option `bless' when yes and are using
+ hfsutils we will `bless' the root directory of the bootstrap
+ filesystem so OF should be able to find and boot the system
+ without reconfiguration.
+
+ * mkofboot/ybin (checkconf): Add validation for the new `bless'
+ option. Also add check that the wrapper, if defined, exists and we
+ have permission to it.
+
+2000-01-04 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.3.
+
+ * ybin (util_install): Quote the filetype/creator arguments to
+ hattrib to prevent the shell from interpreting any meta-characters
+ in some cases. Also no longer try and set metadata on wrapper if
+ there is no wrapper.
+
+ * mkofboot: When creating hfs or dos filesystems give them volume
+ label of "bootstrap".
+
+2000-01-03 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.2.
+
+ * mkofboot: added -w switch to grep when checking if a filesystem
+ is already mounted to prevent erroneous positive matches.
+
+ * ybin (util_install): Add check to make sure that the target
+ device is not mounted as a filesystem before mucking with it.
+
+ * Added changelog.
+
+2000-01-01 Ethan Benson <erbenson@alaska.net>
+
+ * Version 0.1.
+
+ * first version.
+
+End:
--- /dev/null
+This is a new OpenFirmware CHRP script designed to be automatically
+configured by ybin. It is more robust then previous CHRP scripts, it
+includes the following capabilities:
+
+* Multibooting GNU/Linux, MacOS 8.* or 9.* MacOSX, Darwin, direct from
+* CDROM, Network and into an OpenFirmware prompt.
+
+* Presenting a real menu of OS choices.
+
+* Automatic configuration by ybin. This script should NOT be edited
+ by the user. It should also not be used without ybin, its not
+ directly useable by OpenFirmware.
+
+* Configurable colors. (see the yaboot.conf(5) man page).
+
+The multiboot menu is only presented when an extra OS is defined in
+/etc/yaboot.conf, otherwise this script loads yaboot without any user
+interaction.
+
+To enable a multi boot menu add bsd=ofpath and/or macos=ofpath and/or
+macosx=ofpath, and/or darwin=ofpath where ofpath is the OpenFirmware
+device path to the MacOS or MacOSX boot partition. Example:
+macos=hd:10 you can also specify a unix device node, ie: /dev/hda5,
+and ybin will translate it automatically using ofpath.
+
+This script when presenting a dual boot menu will wait for a defined
+number of seconds before automatically booting the default OS. Both
+this delay and the default OS can be configured in /etc/yaboot.conf.
+
+The delay is configured by adding delay=seconds. Unlike timeout this
+is in seconds rather then 10ths of seconds. This option has no effect
+on the yaboot boot: prompt timeout. If delay= is not set, ybin will
+translate the value of timeout= to seconds and use that.
+
+The default OS is configured by adding defaultos=macos. There is only
+four values that are acceptable: linux, bsd, macos, macosx and darwin. The
+default is linux. This should not be confused with yaboot's
+`default=' variable.
+
+The name and letter used to load MacOS or MacOSX (M and X
+respectively) cannot be be configured. (others are D for Darwin, C
+for CDROM, N for network, and O for OpenFirmware)
+
+The Forth code in this script was written by Chris Emerson and iNOUE Koich!.
+
+This script has only been formally tested on a Rev 1 Blue G3, a G4,
+and an ibook, please report any incompatibilities.
--- /dev/null
+This utility is used to find the OpenFirmware device path to a unix
+device node (ie /dev/hda2).
+
+Ofpath will work on Newworld PowerMacs only if yaboot is used as the
+bootloader, it will not work on newworld macs booted with BootX.
+
+Ofpath will also work on most Oldworld PowerMacs, unlike Newworld, it
+will work on BootX booted Oldworld machines. Note that oldworld
+support is not well tested and may not give accurate results.
+
+ofpath supports the following command line switches:
+
+ --debug print boring junk only useful for debugging
+ -h, --help display this help and exit
+ -V, --version output version information and exit
+
+Ybin will use this utility automatically to find the OpenFirmware
+device path when macos=, macosx= are set to unix device nodes in
+/etc/yaboot.conf, and/or if ofboot= is not defined.
+
+ofpath is based on show_of_path.sh written by Olaf Hering, this
+version unlike show_of_path.sh works with /bin/ash and is fully
+functional on stripped down systems such as boot or rescue floppies.
+It has been tested on the Debian GNU/Linux 2.2 (potato) boot
+floppies.
--- /dev/null
+RS/6000 yaboot Notes
+---------------------
+
+A. System Partitioning:
+ 1. Only FDISK partitioning has been tested on the RS/6000.
+ However, yaboot does support mac partitions on a mac, so they should
+ work on an RS/6000 if you really want to go that route.
+ 2. Extended FDISK partitions have not been tested and are not expected to
+ work at this time.
+ 3. yaboot must be installed by itself in a bootable partition of type 0x41.
+ This partition must be less than 10MB.
+
+ Recommended partition configuration:
+ /dev/sda1 : PREP Boot. Type 0x41. Size = 4 MB
+ /dev/sda2 : Linux swap. Type 0x82. Size = 128 MB
+ /dev/sda3 : Linux native. Type 0x83.
+
+B. Building & Installation:
+ 1. See the partitioning section for notes & examples on how to configure
+ your system partitions when installing Linux.
+ 2. Build yaboot by doing:
+ make clean; make
+ 3. Install yaboot by doing (as root):
+ dd if=yaboot of=/dev/sdax
+ where x is the boot partition; for example: dd if=yaboot of=/dev/sda1
+ 4. Make a yaboot.conf file in /etc/yaboot.conf
+
+C. Configuration File (/etc/yaboot.conf):
+ 1. See the ybin documentation for the full range of options.
+ 2. Options tested on an RS/6000 include:
+ timeout = <time in tenths of a second>
+ default = <default label>
+ root= <device containing the root filesystem>
+ image = <path to vmlinux kernel file>
+ label = <short name for this image>
+
+ 3. Examples:
+
+ ## example /etc/yaboot.conf for RS/6000
+ ## Timeout value is in tenths of a second
+ timeout=200
+ default=linux
+
+ image=/boot/vmlinux
+ label=linux
+ root=/dev/sda3
+
+ image=/boot/vmlinux.new
+ label=new
+ root=/dev/sda3
+
+
+D. Tested Configurations:
+ 1. RS/6000 Model 150 (PPC 604e; CHRP IBM,7043-150)
+
+ fdisk -l /dev/sda
+
+ Disk /dev/sda: 64 heads, 32 sectors, 8678 cylinders
+ Units = cylinders of 2048 * 512 bytes
+
+ Device Boot Start End Blocks Id System
+ /dev/sda1 * 1 9 9200 41 PPC PReP Boot
+ /dev/sda2 10 2010 2049024 83 Linux
+ /dev/sda3 2011 2139 132096 82 Linux swap
+
+ 2. RS/6000 Model 260 (PPC 630; CHRP IBM,7043-260)
+
+ * Set "CONFIG_PPC64BRIDGE = y" in the Makefile!
+
+ 3. RS/6000 Model F50 (PPC 630; CHRP IBM,7025-F50)
+
+
+E. Other Documentation:
+ 1. The ybin distribution includes addition README files and
+ man pages.
+
+F. Questions & comments can be directed to:
+ engebret@us.ibm.com or
+ bergner@us.ibm.com
+
--- /dev/null
+This script is deprecated in favor of a much nicer and more robust
+script ofboot, see README.ofboot for more information.
+
+This script was written by Benjamin Herrenschmidt, I added a X to the
+OpenFirmware pathnames, you should replace that X with the proper
+partition number. for the MacOS line add the partition number of your
+MacOS partition, for the yaboot line add the partition number of your
+bootstrap partition, which should be the same partition you configure
+ybin to install on.
+
+Remember that the Mac partition table is considered a partition in and
+of itself, so partition number 1 is always the partition table. If the
+disk is shared with MacOS it needs to have a MacOS disk driver
+partition in which case the first `real' partition will probably be
+number 4.
+
+Edit this script before running ybin or mkofboot.
+
+If you have G4 hardware then your OpenFirmware may already have a
+graphical boot selector built in, this selector can be accessed by
+holding down the option key when booting the machine. You should see
+a screen with buttons for each bootable partition. This version of
+ofboot.b includes a badge icon, the button with a penguin icon is your
+bootstrap partition. If you decide to use this built in selector you
+really do not need to use dualboot.chrp. Thanks to Nicholas Humfrey
+for creating the Badge icon.
--- /dev/null
+The file `large-penguin.mbicon' (mbicon == MultiBoot Icon) is an icon
+that will replace the disk-icon-with-small-penguin-badge in the
+OpenFirmware multi-boot screen (hold down option on AGP G4s and
+iBooks). In order to use this copy an uncompressed copy somewhere,
+and add `icon=/path/to/large-penguin.mbicon' or whatever to
+/etc/yaboot.conf and run ybin. You can add other types of icons so
+long as you put the proper bootinfo tags around them.
+
+This is unsupported and you are on your own.
--- /dev/null
+This is the old basic ofboot.b wrapper, it has been replaced by a more
+robust CHRP script that is able to dual or tri-boot GNU/Linux, MacOS,
+and MacOS X. See README.ofboot.b for more information.
+
+OpenFirmware on newworld macs by default searches for HFS partitions
+with a `blessed' directory, and then checks for a file with an HFS
+filetype of `tbxi' if found it loads this file. Unfortunately OF is
+being far to picky about the format of this file, while it will load a
+ELF executable just fine when directed to, if the tbxi file it finds
+is just a plain ELF executable, as yaboot is, then it refuses to load
+it.
+
+The best longterm solution is to embed a small CHRP boot script to the
+head of of the yaboot executable, but until we can find the right way
+to do that we can use a small wrapper instead. The file included
+called simple_ofboot.b does nothing more then run the OF command "boot
+hd:,\\yaboot" which should load the yaboot executable on most machines
+if you use the stock internal hard disk. You might have to change
+that device path (hd:) to match the device path to your bootstrap
+partition, such as hd:2,\\yaboot. Or you can dispense with the
+wrapper altogether and reset the boot-device variable in OF to point
+directly at the yaboot executable and that will work too. This
+wrapper just allows for most (hopefully) machines to boot
+transparently without any OF reconfiguration.
+
+If you have G4 hardware then your OpenFirmware may already have a
+graphical boot selector built in, this selector can be accessed by
+holding down the option key when booting the machine. You should see
+a screen with buttons for each bootable partition. This version of
+ofboot.b includes a badge icon, the button with a penguin icon is your
+bootstrap partition. If you decide to use this built in selector you
+really do not need to use the menu_ofboot.b script provided in this
+package. Thanks to Nicholas Humfrey for creating the Badge icon.
+
+Hopefully soon these problems will have better solutions at some
+point. If you happen to know OF well and have any suggestions they are
+most welcome!
--- /dev/null
+<CHRP-BOOT>
+<COMPATIBLE>
+MacRISC
+</COMPATIBLE>
+<DESCRIPTION>
+GNU/Linux PowerPC Boot chooser
+</DESCRIPTION>
+<BOOT-SCRIPT>
+" get-key-map" " keyboard" open-dev $call-method
+dup 20 dump
+5 + c@ 08 = if
+" Booting MacOS ..." cr " boot hd:X,\\:tbxi" eval
+else
+" Booting Yaboot ..." cr " boot hd:X,yaboot" eval
+then
+</BOOT-SCRIPT>
+<OS-BADGE-ICONS>
+1010
+000000000000F8FEACF6000000000000
+0000000000F5FFFFFEFEF50000000000
+00000000002BFAFEFAFCF70000000000
+0000000000F65D5857812B0000000000
+0000000000F5350B2F88560000000000
+0000000000F6335708F8FE0000000000
+00000000005600F600F5FD8100000000
+00000000F9F8000000F5FAFFF8000000
+000000008100F5F50000F6FEFE000000
+000000F8F700F500F50000FCFFF70000
+00000088F70000F50000F5FCFF2B0000
+0000002F582A00F5000008ADE02C0000
+00090B0A35A62B0000002D3B350A0000
+000A0A0B0B3BF60000505E0B0A0B0A00
+002E350B0B2F87FAFCF45F0B2E090000
+00000007335FF82BF72B575907000000
+000000000000ACFFFF81000000000000
+000000000081FFFFFFFF810000000000
+0000000000FBFFFFFFFFAC0000000000
+000000000081DFDFDFFFFB0000000000
+000000000081DD5F83FFFD0000000000
+000000000081DDDF5EACFF0000000000
+0000000000FDF981F981FFFF00000000
+00000000FFACF9F9F981FFFFAC000000
+00000000FFF98181F9F981FFFF000000
+000000ACACF981F981F9F9FFFFAC0000
+000000FFACF9F981F9F981FFFFFB0000
+00000083DFFBF981F9F95EFFFFFC0000
+005F5F5FDDFFFBF9F9F983DDDD5F0000
+005F5F5F5FDD81F9F9E7DF5F5F5F5F00
+0083DD5F5F83FFFFFFFFDF5F835F0000
+000000FBDDDFACFBACFBDFDFFB000000
+000000000000FFFFFFFF000000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFFFF00000000
+00000000FFFFFFFFFFFFFFFFFF000000
+00000000FFFFFFFFFFFFFFFFFF000000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+00FFFFFFFFFFFFFFFFFFFFFFFFFF0000
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00FFFFFFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFF000000
+</OS-BADGE-ICONS>
+</CHRP-BOOT>
--- /dev/null
+<OS-VOLUME-ICONS>
+00400040
+818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181FB
+812B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2BF8AC
+812B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002BFAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F8FBFEFFFFFDFB56F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FBFFFFFFFFFFFFFFFFFC2BF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FBFFFFFFFFFFFFFFACFBFEFD2BF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F7FFFFFFFFFFFFFFFFFCFBFDFFFBF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F681FFFFFFFFFFFFFFFFFEFFFFFFFFF7F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FBFFFFFFFFFFFFFFFFFFFFFFFFFF81F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FCFFFEFEFEFFFFFFFDACACFFFFFFACF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FCFEF956FDFFFFFBF8F7FAFEFFFFFDF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FCFCF82BF9FFFEF6F8F82BFDFFFFFFF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F68181FEFBF7FEACF6FFACF881FFFFFFF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F681FCACFE335F8357FFFF56FAFFFFFFF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F681FE565F0B0B2F2E595E2BFDFFFFFFF7F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F9FE5F110B0B0A0A2F2F2FADFFFFFF56F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F989350B0B0B0A2F2F353589FFFFFFF9F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F9FE5F0B0B0A2F59353535FDFEFCFEACF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F8AC565F353535353533F7FAFF8181FF56F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FAACF7565F3B5F34F82BF5F6FEFEFDFFACF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F7FEFCF5F7F7F8F7F7F6F50000FAFFFFFFFFF9F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6ACFEF700F6F7F72BF500000000F6FEFFFFFFFE2BF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FBFFFA000000F5F5F500000000000081FFFFFFFFFCF6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FFFEF6000000000000000000000000F8FFFFFFFFFF81F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F7FEFFFCF6000000F5F5000000F5F5F5F6F5FEFFFFFFFFFF56F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6ACFFFFFAF7F50000F5F5000000F5F62BF72BF9FFFEFFFFFFFE2BF6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F7FFFEFE2BF5000000F5000000000000F5F52BF6FEFFFDFFFFFF81F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FAFEFEFAF500000000000000000000000000F5F6F9FFFEFEFFFFFE2BF6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FDFDFEF600000000000000000000000000000000F6FEACFDFEFFFF56F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F8FFFEFA0000000000F5F50000000000000000000000FCFEFFFDFFFFFCF6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6FBFEFFF60000000000F500000000000000000000000081FFFFFEFFFFFE2BF6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F62BE0FEAC000000000000F5000000000000000000000000FAFFFFFEFFFFFF56F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6FBFFFE81000000000000F500000000000000000000000056FFFFFEFFFFFF81F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F656FFFFFD81000000000000F500000000000000000000000056FFFFFEFFFFFFFCF6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6FAFFFEACF9000000000000F5000000000000000000000000F8FFFEFFFFFFFFFBF6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6FAE089FDF8000000000000F5000000000000000000000000F9FEFEFEFEFEFF81F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F62C350B59FCF60000000000F50000000000000000000001085EFFFFFFFFFDFEF9F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6340B0B0B59AC2B00000000F5000000000000000000000A0B34FFFFFFFFFE592DF6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F633350B0B0B0B83FEF8000000F5000000000000000000F52E0B35E0FFFFFF830B0AF6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F62C3334350B0B0B0B0B2FFEFF560000000000000000000000F52B340B355FADAD83350B0AF6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F634110B0B0B0B0B0B0B0B0B5FFFFF81F5000000000000000000F52B341135353535350B0B0B09F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6340B0B0B0B0B0B0B0B0B0B0BADFFFF56000000000000000000002B5835113535350B0B0B0B0B08F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6330B0B0B0B0B0B0B0B0B0B0B35E0FF5600000000000000000000F85F350B0B0B0B0B0B0B0B0B0B09F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F633110B0B0B0B0B0B0B0B0B0B0B582B00000000000000000000F8FE5F350B0B0B0B0B0B0B0B0B0B0B0AF6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F633110B0B0B0B0B0B0B0B0B0B0B2F2C0000000000000000F581FFE05F350B0B0B0B0B0B0B0B0B0B0B08F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F634110B0B0B0B0B0B0B0B0B0B0B355FF8F5000000F52BF9FDFFFFFE5F350B0B0B0B0B0B0B0B0B0A2CF6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6353535110B0B0B0B0B0B0B0B0B353BADFEACFCFDFFFFFFFFFFFFAD3B350B0B0B0B0B0B0B342CF6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F63335353535353535110B0B0B0B355FADFFFFFFFFFFFFFFFFFFFFAD5F35110B0B11353533F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F733585F5F3B35353535355F5FADFDFCFB818181818181FCAC5F3B353535355F32F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F62BF8575E5F5F5F5F8382F8F6F6F6F6F6F6F6F6F6F6F8895F5F3B5F5FF7F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F75D83895D2BF6F6F6F6F6F6F6F6F6F6F6F6568889895DF7F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B00F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F656FAAC
+812B2B5656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656FAAC
+81F8FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAAC
+FBACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACAC
+FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFD
+FEFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFAFC
+FEFC8181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181F9F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F981ACFEFFFFFEAC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFFFFFFFFFFFFFFFFACFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFFFFFFFFFFFFFFACFBFEFEFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFFFFFFFFFFFFFFFFFCFBFDFFACF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FCFFFFFFFFFFFFFFFFFEFFFFFFFFFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFFFFFFFFFFFFFFFFFFFFFFFFFFFCF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FDFFFEFEFEFFFFFFFDACACFFFFFFFDF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FDFEF956FDFFFFFBF8F7FAFEFFFFFEF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FDFCF82BF9FFFEF6F8F82BFDFFFFFFF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FC81FEFBF7FEACF6FFACF881FFFFFFF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FCFCACFE335F8357FFFF56FAFFFFFFF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FCFE565F0B0B2F2E595E2BFDFFFFFFFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FBFE5F110B0B0A0A2F2F2FADFFFFFF81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FB89350B0B0B0A2F2F353589FFFFFFFBF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FBFE5F0B0B0A2F59353535FDFEFCFEFDF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F981AC565F353535353533F7FAFF8181FFFBF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FCACF7565F3B5F34F82BF5F6FEFEFDFFFDF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFFFCF5F7F7F8F7F7F6F50000FAFFFFFFFFFBF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FDFEF700F6F7F72BF500000000F6FEFFFFFFFEFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFFFA000000F5F5F500000000000081FFFFFFFFFDF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F981FFFEF6000000000000000000000000F8FFFFFFFFFFFCF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFEFFFCF6000000F5F5000000F5F5F5F6F5FEFFFFFFFFFFFBF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FDFFFFFAF7F50000F5F5000000F5F62BF72BF9FFFEFFFFFFFEFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFFFEFE2BF5000000F5000000000000F5F52BF6FEFFFDFFFFFFFCF9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FCFEFEFAF500000000000000000000000000F5F6F9FFFEFEFFFFFFF9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FEFDFEF600000000000000000000000000000000F6FEACFDFEFFFF81F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F981FFFEFA0000000000F5F50000000000000000000000FCFEFFFDFFFFFDF9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFEFFF60000000000F500000000000000000000000081FFFFFEFFFFFFF9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFFFEAC000000000000F5000000000000000000000000FAFFFFFEFFFFFFFBF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFFFE81000000000000F500000000000000000000000056FFFFFEFFFFFFFCF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F981FFFFFD81000000000000F500000000000000000000000056FFFFFEFFFFFFFDF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9FCFFFEACF9000000000000F5000000000000000000000000F8FFFEFFFFFFFFACF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9FCE089FDF8000000000000F5000000000000000000000000F9FEFEFEFEFEFFFCF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F957350B59FCF60000000000F50000000000000000000001085EFFFFFFFFFDFEFBF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9340B0B0B59AC2B00000000F5000000000000000000000A0B34FFFFFFFFFE592EF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F958350B0B0B0B83FEF8000000F5000000000000000000F52E0B35E0FFFFFF830B2EF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9573434350B0B0B0B0B2FFEFF560000000000000000000000F52B340B355FADAD83350B0BF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F934110B0B0B0B0B0B0B0B0B5FFFFF81F5000000000000000000F52B341135353535350B0B0B34F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9340B0B0B0B0B0B0B0B0B0B0BADFFFF56000000000000000000002B5835113535350B0B0B0B0B33F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9340B0B0B0B0B0B0B0B0B0B0B35E0FF5600000000000000000000F85F350B0B0B0B0B0B0B0B0B0B34F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F934110B0B0B0B0B0B0B0B0B0B0B582B00000000000000000000F8FE5F350B0B0B0B0B0B0B0B0B0B0B2EF9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F934110B0B0B0B0B0B0B0B0B0B0B2F2C0000000000000000F581FFE05F350B0B0B0B0B0B0B0B0B0B0B33F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F934110B0B0B0B0B0B0B0B0B0B0B355FF8F5000000F52BF9FDFFFFFE5F350B0B0B0B0B0B0B0B0B3457F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9353535110B0B0B0B0B0B0B0B0B353BADFEACFCFDFFFFFFFFFFFFAD3B350B0B0B0B0B0B0B3457F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9585F353535353535110B0B0B0B355FADFFFFFFFFFFFFFFFFFFFFAD5F35110B0B1135355EF9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9FA5D5E5F5F3B35353535355F5FADFEFDACFCFCFCFCFCFCACAD5F3B353535355F5DF9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9FA82825F5F5F5F838981F9F9F9F9F9F9F9F9F9F981895F5F3B5F5FFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FA82898982FAF9F9F9F9F9F9F9F9F9F9F9F98189898982FAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFCF95656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656F7FC
+FEFAF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7FC
+FDFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
+FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFD
+FEFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFAFC
+FEFC8181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181F9F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F981ACFEFFFFFEAC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFFFFFFFFFFFFFFFFACFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFFFFFFFFFFFFFFFDACFEFEFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFFFFFFFFFFFFFFFFFDACFEFFACF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FCFFFFFFFFFFFFFFFFFEFFFFFFFFFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFFFFFFFFFFFFFFFFFFFFFFFFFFFCF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FDFFFFFEFEFFFFFFFEFDFDFFFFFFFDF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FDFEFBFBFEFFFFAC81FAFCFFFFFFFEF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FDAC81FAFBFFFEF98181FAFEFFFFFFF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FCFCFEACFAFEFDF9FFFD81FCFFFFFFF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FCFDFDFE8289AD82FFFFFBFCFFFFFFF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FCFF81895F5F5F5F8388FAFEFFFFFFFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FBE0895F5F5F5E5E5F5F5FADFFFFFF81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FBAD835F5F5F5E5F5F8383ADFFFFFFFBF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FBE0895F5F5F8383835F83FEF4ACFEFDF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F981FDFB89838383838382FAFCFFACACFFFBF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FCFDFAFB8989898281FAF9F9FEFFFEFFFDF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFFFDF9FA818181FAF9565656FCFFFFFFFFFBF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FDFEFA56F9FAFAFAF956565656F9FEFFFFFFFFFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFFFC565656F9F956565656565656ACFFFFFFFFFDF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F981FFFEF956565656565656565656565681FFFFFFFFFFFCF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFEFFFDF9565656F9F956565656F9F9F9F9FEFFFFFFFFFFFBF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FDFFFFFCFAF95656F956565656F9F9FAFAFAFBFFFEFFFFFFFEFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFFFEFEFA565656565656565656565656F9FAF9FEFFFEFFFFFFFCF9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FCFFFEFC565656565656565656565656565656F9FBFFFEFEFFFFFFF9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FEFEFEF956565656565656565656565656565656F9FEFDFEFFFFFF81F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F981FFFEFC565656565656565656565656565656565656FDFFFFFEFFFFFDF9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFEFFF95656565656F9565656565656565656565656ACFFFFFEFFFFFFF9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFFFEFD565656565656F9565656565656565656565656FCFFFFFEFFFFFFFBF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9ACFFFEFC565656565656F9565656565656565656565656FBFFFFFEFFFFFFFCF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F981FFFFFEFC565656565656F9565656565656565656565656FBFFFFFEFFFFFFFDF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9FCFFFFFDFB565656565656F956565656565656565656565681FFFEFFFFFFFFACF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9FCE0ADFE81565656565656F9565656565656565656565656FBFFFEFFFEFEFFFCF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9815F5F83ACF95656565656F956565656565656565656F95788FFFFFFFFFEFEFBF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F95F5F5F5F83FDFA56565656F9565656565656565656565E5F83FFFFFFFFE0835EF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9825F5F5F5F5FADFE8156565656565656565656565656565E5F83FFFFFFFFAD5F5FF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F95D5E835F5F5F5F5F5F5FE0FFFB565656565656565656565656FA5E5F8389DFDFAD5F5F5FF9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9825F5F5F5F5F5F5F5F5F5F89FFFFACF956565656565656565656FA825F5F8383835F5F5F5F5EF9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9825F5F5F5F5F5F5F5F5F5F5FADFFFFFB56565656565656565656FA825F5F5F5F5F5F5F5F5F5F5DF9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F95E5F5F5F5F5F5F5F5F5F5F5F83E0FFFB5656565656565656565681895F5F5F5F5F5F5F5F5F5F5F5EF9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9825F5F5F5F5F5F5F5F5F5F5F5F83FA5656565656565656565681E0895F5F5F5F5F5F5F5F5F5F5F5F5EF9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F95E5F5F5F5F5F5F5F5F5F5F5F5F5F815656565656565656F9FCFFE0895F5F5F5F5F5F5F5F5F5F5F5F5DF9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F95E5F5F5F5F5F5F5F5F5F5F5F5F5F89815656565656FAFBFEFFFFE0895F5F5F5F5F5F5F5F5F5F5FFAF9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F95F5F5F5F5F5F5F5F5F5F5F5F5F5F89E0FEFDFDFEFFFFFFFFFFFFDF895F5F5F5F5F5F5F5F5F5DF9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F98283838383835F5F5F5F5F5F5F8389DFFFFFFFFFFFFFFFFFFFFFDF89835F5F5F5F5F8382F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9FA828289898983835F5F838989E0FEFDACFCFCFCFCFCFCACFD8989838383838981F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F981828889898989ADAD81F9F9F9F9F9F9F9F9F9F981AD8989898989FAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9FAFCADADFCFAF9F9F9F9F9F9F9F9F9F9F9F9FBADADADFCFAF9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFC81F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F9F956F7FC
+FEFCF95656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656F7FC
+FEFAF7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7FC
+FDFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+</OS-VOLUME-ICONS>
--- /dev/null
+<CHRP-BOOT>
+<COMPATIBLE>
+MacRISC
+</COMPATIBLE>
+<DESCRIPTION>
+GNU/Linux PPC bootloader
+</DESCRIPTION>
+<BOOT-SCRIPT>
+boot hd:,\\yaboot
+</BOOT-SCRIPT>
+<OS-BADGE-ICONS>
+1010
+000000000000F8FEACF6000000000000
+0000000000F5FFFFFEFEF50000000000
+00000000002BFAFEFAFCF70000000000
+0000000000F65D5857812B0000000000
+0000000000F5350B2F88560000000000
+0000000000F6335708F8FE0000000000
+00000000005600F600F5FD8100000000
+00000000F9F8000000F5FAFFF8000000
+000000008100F5F50000F6FEFE000000
+000000F8F700F500F50000FCFFF70000
+00000088F70000F50000F5FCFF2B0000
+0000002F582A00F5000008ADE02C0000
+00090B0A35A62B0000002D3B350A0000
+000A0A0B0B3BF60000505E0B0A0B0A00
+002E350B0B2F87FAFCF45F0B2E090000
+00000007335FF82BF72B575907000000
+000000000000ACFFFF81000000000000
+000000000081FFFFFFFF810000000000
+0000000000FBFFFFFFFFAC0000000000
+000000000081DFDFDFFFFB0000000000
+000000000081DD5F83FFFD0000000000
+000000000081DDDF5EACFF0000000000
+0000000000FDF981F981FFFF00000000
+00000000FFACF9F9F981FFFFAC000000
+00000000FFF98181F9F981FFFF000000
+000000ACACF981F981F9F9FFFFAC0000
+000000FFACF9F981F9F981FFFFFB0000
+00000083DFFBF981F9F95EFFFFFC0000
+005F5F5FDDFFFBF9F9F983DDDD5F0000
+005F5F5F5FDD81F9F9E7DF5F5F5F5F00
+0083DD5F5F83FFFFFFFFDF5F835F0000
+000000FBDDDFACFBACFBDFDFFB000000
+000000000000FFFFFFFF000000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFFFF00000000
+00000000FFFFFFFFFFFFFFFFFF000000
+00000000FFFFFFFFFFFFFFFFFF000000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+00FFFFFFFFFFFFFFFFFFFFFFFFFF0000
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00FFFFFFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFF000000
+</OS-BADGE-ICONS>
+</CHRP-BOOT>
--- /dev/null
+## Example yaboot.conf for ybin and yaboot >= 0.6
+## see man yaboot.conf for more details.
+
+## This example shows how to multi boot GNU/Linux, MacOS, MacOSX, and
+## Darwin with SCSI disks. This example also creates menu items for
+## booting from the CDROM, the Network and into an OpenFirmware
+## prompt.
+
+## Change to your bootstrap partition ie: /dev/sda2
+boot=unconfigured
+
+## device is the OpenFirmware device path to the disk containing
+## kernel images. if your disk is /dev/hda you can find the
+## OpenFirmware path by running the command: ofpath /dev/hda
+
+device=/pci@80000000/pci-bridge@d/ADPT,2930CU@2/@1:
+
+## partition is the partition number where the kernel images are
+## located. The kernel images should be on your root filesystem, so
+## this is usually the same partition number as your root filesystem.
+## so if root = /dev/hda3 (the 3rd partition) then you should have
+## partition=3 This *MUST* be set correct or yaboot won't boot! This
+## option can be either set globally as shown here, or per image in
+## the image= sections.
+
+partition=3
+
+## 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)
+## will wait before choosing the default OS (GNU/Linux or the value of
+## defaultos=). If you omit this then the value of timeout=
+## (converted to seconds) will be used.
+
+delay=10
+
+## timeout is the amount of time in tenths of a second that yaboot
+## will wait before booting the default kernel image (the first image=
+## section in this config file or the value of default=).
+
+timeout=20
+install=/usr/local/lib/yaboot/yaboot
+magicboot=/usr/local/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
+
+## Password supplied in plaintext, required for yaboot to boot, unless
+## restricted is also present (see below). Be sure to
+## chmod 600 /etc/yaboot.conf if you set this!
+
+#password=secret
+
+## Password supplied as an md5 hash, see above
+
+#password=$1$saltstri$WHZcnT3IOdSrMvizOq7Ht1
+
+## 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.
+## arbitrary file load). restricted can also be placed in an image
+## section in that case any image not including the restricted keyword
+## will be fully password protected.
+
+#restricted
+
+## image is the kernel itself, commonly kept in / but also commonly
+## found in /boot. Note that /boot should generally not be its own
+## partition on powerpcs, its not necessary and complicates things.
+## Make sure /boot is on the partition specified by partition= see
+## above. /boot should never be an HFS filesystem. You may point
+## image= to a symbolic link so long as the symlink does not cross
+## partition boundries.
+
+image=/vmlinux
+ label=Linux
+ root=/dev/sda3
+ read-only
+
+image=/vmlinux.old
+ label=Linux.old
+ root=/dev/sda3
+ read-only
+
+## The {macos,macosx,darwin} variables can be either a unix /dev node or an
+## OpenFirmware path, as shown here:
+
+## if you have the bsd bootloader installed on ybin bootstrap
+## partition as ofwboot.elf
+bsd=/dev/sda2
+
+## unix node
+macos=/dev/sda8
+
+## OpenFirmware path, this would likely be /dev/sda9 if you used a
+## unix node instead.
+macosx=/pci@80000000/pci-bridge@d/ADPT,2930CU@2/@1:9
+
+darwin=/pci@80000000/pci-bridge@d/ADPT,2930CU@2/@1:10
+
+## Add a menu entry to boot from the CDROM:
+
+enablecdboot
+
+## Add a menu entry to boot from the Network:
+
+enablenetboot
+
+## Add a menu entry to boot into an OpenFirmware prompt:
+
+enableofboot
--- /dev/null
+## Example yaboot.conf for ybin and yaboot >= 0.6
+## see man yaboot.conf for more details.
+
+## Change `unconfigured' to your bootstrap partition ie: /dev/hda2
+boot=unconfigured
+
+## fstype=raw is what makes ybin dd yaboot to the bootstrap partition
+## instead of using a filesystem.
+
+fstype=raw
+
+## device is the OpenFirmware device path to the disk containing
+## kernel images. if your disk is /dev/hda you can find the
+## OpenFirmware path by running the command: ofpath /dev/hda DO NOT
+## specify a partition number for this! This is generally not
+## necessary for IBM hardware
+
+#device=hd:
+
+## partition is the partition number where the kernel images are
+## located. The kernel images should be on your root filesystem, so
+## this is usually the same partition number as your root filesystem.
+## so if root = /dev/hda3 (the 3rd partition) then you should have
+## partition=3 This *MUST* be set correct or yaboot won't boot! This
+## option can be either set globally as shown here, or per image in
+## the image= sections
+
+partition=3
+
+## timeout is the amount of time in tenths of a second that yaboot
+## will wait before booting the default kernel image (the first image=
+## section in this config file or the value of default=).
+
+timeout=20
+install=/usr/local/lib/yaboot/yaboot
+
+## nonvram is required for IBM hardware currently since ofpath does
+## not support them, it is also probably not necessary.
+
+nonvram
+
+## Password supplied in plaintext, required for yaboot to boot, unless
+## restricted is also present (see below). Be sure to
+## chmod 600 /etc/yaboot.conf if you set this!
+
+#password=secret
+
+## Password supplied as an md5 hash, see above
+
+#password=$1$saltstri$WHZcnT3IOdSrMvizOq7Ht1
+
+## 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.
+## arbitrary file load). restricted can also be placed in an image
+## section in that case any image not including the restricted keyword
+## will be fully password protected.
+
+#restricted
+
+## image is the kernel itself, commonly kept in / but also commonly
+## found in /boot. Note that /boot should generally not be its own
+## partition on powerpcs, its not necessary and complicates things.
+## Make sure /boot is on the partition specified by partition= see
+## above. /boot should never be an HFS filesystem. You may point
+## image= to a symbolic link so long as the symlink does not cross
+## partition boundries.
+
+image=/vmlinux
+ label=Linux
+ root=/dev/sda3
+ read-only
--- /dev/null
+## Example yaboot.conf for ybin and yaboot >= 0.6
+## see man yaboot.conf for more details.
+
+## Change `unconfigured' to your bootstrap partition eg: /dev/hda2
+boot=unconfigured
+
+## device is the OpenFirmware device path to the disk containing
+## kernel images. if your disk is /dev/hda you can find the
+## OpenFirmware path by running the command: ofpath /dev/hda DO NOT
+## specify a partition number for this! On IBM hardware you can
+## generally comment this out.
+
+device=hd:
+
+## partition is the partition number where the kernel images are
+## located. The kernel images should be on your root filesystem, so
+## this is usually the same partition number as your root filesystem.
+## so if root = /dev/hda3 (the 3rd partition) then you should have
+## partition=3 This *MUST* be set correct or yaboot won't boot! This
+## option can be either set globally as shown here, or per image in
+## the image= sections
+
+partition=3
+
+## 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)
+## will wait before choosing the default OS (GNU/Linux or the value of
+## defaultos=). If you omit this then the value of timeout=
+## (converted to seconds) will be used.
+
+delay=10
+
+## timeout is the amount of time in tenths of a second that yaboot
+## will wait before booting the default kernel image (the first image=
+## section in this config file or the value of default=).
+
+timeout=40
+install=/usr/local/lib/yaboot/yaboot
+magicboot=/usr/local/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
+
+## Password supplied in plaintext, required for yaboot to boot, unless
+## restricted is also present (see below). Be sure to
+## chmod 600 /etc/yaboot.conf if you set this!
+
+#password=secret
+
+## Password supplied as an md5 hash, see above
+
+#password=$1$saltstri$WHZcnT3IOdSrMvizOq7Ht1
+
+## 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.
+## arbitrary file load). restricted can also be placed in an image
+## section in that case any image not including the restricted keyword
+## will be fully password protected.
+
+#restricted
+
+## image is the kernel itself, commonly kept in / but also commonly
+## found in /boot. Note that /boot should generally not be its own
+## partition on powerpcs, its not necessary and complicates things.
+## Make sure /boot is on the partition specified by partition= see
+## above. /boot should never be an HFS filesystem. You may point
+## image= to a symbolic link so long as the symlink does not cross
+## partition boundries.
+
+image=/vmlinux
+ label=Linux
+ root=/dev/hda3
+ read-only
+
+image=/vmlinux.old
+ label=Linux.old
+ root=/dev/hda3
+ read-only
--- /dev/null
+#%ybinscript-1.1
+
+## THIS IS NOT A CONFFILE DO NOT EDIT !!!
+
+###############################################################################
+##
+## ofboot first stage autoconfiguring bootloader for yaboot and ybin
+## Copyright (C) 2000, 2001 Ethan Benson
+##
+## Forth code written by Chris Emerson
+##
+## Copyright (C) 2000, 2001 Chris Emerson
+##
+## Portions of Forth code also written by iNOUE Koich!
+##
+## Copyright (C) 2000, 2001 iNOUE Koich!
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+###############################################################################
+
+## THIS IS NOT A CONFFILE DO NOT EDIT !!!
+##
+## This script is not meant to be called directly, only by ybin.
+##
+## Usage: OS-count defaultos timeout fgc bgc osname oslabel oskey osdev osfile ...
+
+DEBUG=0
+PRG=ofboot
+
+## make sure we are called at least somewhat sanely.
+if [ $# = 0 ] ; then
+ echo 1>&2 "$PRG: Need arguments"
+ exit 1
+fi
+
+if [ $# != "$(($1 * 5 + 5))" ] ; then
+ echo 1>&2 "$PRG: Invalid argument count: $# should be $(($1 * 5 + 5))"
+ exit 1
+fi
+
+if [ "$1" -gt 8 ] ; then
+ echo 1>&2 "$PRG: Maximum number of OSes is currently 8"
+ exit 1
+fi
+
+## we need printf so \n works, but echo -e -n will sometimes do.
+if [ "$(printf printf_test 2>/dev/null)" = printf_test ] ; then
+ PRINTF=printf
+else
+ PRINTF="echo -e -n"
+fi
+
+## make sure echo is not lame if we must use it.
+if [ "$PRINTF" != printf ] ; then
+ if [ "$(echo -e -n echo_test)" != echo_test ] ; then
+ echo 1>&2 "$PRG: printf unavailable and echo is broken, sorry."
+ exit 1
+ fi
+fi
+
+## get first 5 args which are global and dispose of them.
+OSNUM="$1"
+DEFAULTOS="$2"
+TIMEOUT="$3"
+FGCOLOR="$4"
+BGCOLOR="$5"
+shift 5
+
+## is a boot menu actually needed?
+if [ "$OSNUM" = 1 ] ; then
+ MENU=0
+else
+ MENU=1
+fi
+
+## create the variables.
+##
+## OSNAME="$1"
+## OSLABEL="$2"
+## OSKEY="$3"
+## OSDEV="$4"
+## OSFILE="$5"
+
+COUNT=1
+while [ "$COUNT" -le "$OSNUM" ] ; do
+ case "$COUNT" in
+ 1)
+ OSNAME1="$1"
+ [ "$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"
+ GETYA=" ascii $3 of \" $3 \"(0d 0a)\" .printf boot$1 endof"
+ shift 5
+ COUNT="$(($COUNT + 1))"
+ ;;
+ 2)
+ [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "$PRG: DEBUG: file2: $5\n"
+ [ "$COUNT" = "$OSNUM" ] && c="."
+ [ "$4" = "quit" ] && BOOT=quit || BOOT="load-base release-load-area \" ${4}${5}\" \$boot"
+ BT2=": boot$1 \" Booting $2...\" .printf 100 ms $BOOT ;"
+ MENU2="\" $3 for $2${c-,}\"(0d 0a)\" .printf"
+ GET2=" ascii $3 of \" $3 \"(0d 0a)\" .printf boot$1 endof"
+ shift 5
+ COUNT="$(($COUNT + 1))"
+ ;;
+ 3)
+ [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "$PRG: DEBUG: file3: $5\n"
+ [ "$COUNT" = "$OSNUM" ] && c="."
+ [ "$4" = "quit" ] && BOOT=quit || BOOT="load-base release-load-area \" ${4}${5}\" \$boot"
+ BT3=": boot$1 \" Booting $2...\" .printf 100 ms $BOOT ;"
+ MENU3="\" $3 for $2${c-,}\"(0d 0a)\" .printf"
+ GET3=" ascii $3 of \" $3 \"(0d 0a)\" .printf boot$1 endof"
+ shift 5
+ COUNT="$(($COUNT + 1))"
+ ;;
+ 4)
+ [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "$PRG: DEBUG: file4: $5\n"
+ [ "$COUNT" = "$OSNUM" ] && c="."
+ [ "$4" = "quit" ] && BOOT=quit || BOOT="load-base release-load-area \" ${4}${5}\" \$boot"
+ BT4=": boot$1 \" Booting $2...\" .printf 100 ms $BOOT ;"
+ MENU4="\" $3 for $2${c-,}\"(0d 0a)\" .printf"
+ GET4=" ascii $3 of \" $3 \"(0d 0a)\" .printf boot$1 endof"
+ shift 5
+ COUNT="$(($COUNT + 1))"
+ ;;
+ 5)
+ [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "$PRG: DEBUG: file5: $5\n"
+ [ "$COUNT" = "$OSNUM" ] && c="."
+ [ "$4" = "quit" ] && BOOT=quit || BOOT="load-base release-load-area \" ${4}${5}\" \$boot"
+ BT5=": boot$1 \" Booting $2...\" .printf 100 ms $BOOT ;"
+ MENU5="\" $3 for $2${c-,}\"(0d 0a)\" .printf"
+ GET5=" ascii $3 of \" $3 \"(0d 0a)\" .printf boot$1 endof"
+ shift 5
+ COUNT="$(($COUNT + 1))"
+ ;;
+ 6)
+ [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "$PRG: DEBUG: file6: $5\n"
+ [ "$COUNT" = "$OSNUM" ] && c="."
+ [ "$4" = "quit" ] && BOOT=quit || BOOT="load-base release-load-area \" ${4}${5}\" \$boot"
+ BT6=": boot$1 \" Booting $2...\" .printf 100 ms $BOOT ;"
+ MENU6="\" $3 for $2${c-,}\"(0d 0a)\" .printf"
+ GET6=" ascii $3 of \" $3 \"(0d 0a)\" .printf boot$1 endof"
+ shift 5
+ COUNT="$(($COUNT + 1))"
+ ;;
+ 7)
+ [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "$PRG: DEBUG: file7: $5\n"
+ [ "$COUNT" = "$OSNUM" ] && c="."
+ [ "$4" = "quit" ] && BOOT=quit || BOOT="load-base release-load-area \" ${4}${5}\" \$boot"
+ BT7=": boot$1 \" Booting $2...\" .printf 100 ms $BOOT ;"
+ MENU7="\" $3 for $2${c-,}\"(0d 0a)\" .printf"
+ GET7=" ascii $3 of \" $3 \"(0d 0a)\" .printf boot$1 endof"
+ shift 5
+ COUNT="$(($COUNT + 1))"
+ ;;
+ 8)
+ [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "$PRG: DEBUG: file8: $5\n"
+ [ "$COUNT" = "$OSNUM" ] && c="."
+ [ "$4" = "quit" ] && BOOT=quit || BOOT="load-base release-load-area \" ${4}${5}\" \$boot"
+ BT8=": boot$1 \" Booting $2...\" .printf 100 ms $BOOT ;"
+ MENU8="\" $3 for $2${c-,}\"(0d 0a)\" .printf"
+ GET8=" ascii $3 of \" $3 \"(0d 0a)\" .printf boot$1 endof"
+ shift 5
+ COUNT="$(($COUNT + 1))"
+ ;;
+ esac
+done
+
+## first OS is reserved.
+if [ "$OSNAME1" != yaboot ] ; then
+ echo 1>&2 "ofboot: first OS must be yaboot"
+ exit 1
+fi
+
+## concatenate the variables together.
+case "$OSNUM" in
+ 1)
+ BOOTVARS="${BTYA}"
+ MENUOPTS="${MENUYA}"
+ GETOS="${GETYA}"
+ ;;
+ 2)
+ BOOTVARS="${BTYA}\n${BT2}"
+ MENUOPTS="${MENUYA}\n${MENU2}"
+ GETOS="${GETYA}\n${GET2}"
+ ;;
+ 3)
+ BOOTVARS="${BTYA}\n${BT2}\n${BT3}"
+ MENUOPTS="${MENUYA}\n${MENU2}\n${MENU3}"
+ GETOS="${GETYA}\n${GET2}\n${GET3}"
+ ;;
+ 4)
+ BOOTVARS="${BTYA}\n${BT2}\n${BT3}\n${BT4}"
+ MENUOPTS="${MENUYA}\n${MENU2}\n${MENU3}\n${MENU4}"
+ GETOS="${GETYA}\n${GET2}\n${GET3}\n${GET4}"
+ ;;
+ 5)
+ BOOTVARS="${BTYA}\n${BT2}\n${BT3}\n${BT4}\n${BT5}"
+ MENUOPTS="${MENUYA}\n${MENU2}\n${MENU3}\n${MENU4}\n${MENU5}"
+ GETOS="${GETYA}\n${GET2}\n${GET3}\n${GET4}\n${GET5}"
+ ;;
+ 6)
+ BOOTVARS="${BTYA}\n${BT2}\n${BT3}\n${BT4}\n${BT5}\n${BT6}"
+ MENUOPTS="${MENUYA}\n${MENU2}\n${MENU3}\n${MENU4}\n${MENU5}\n${MENU6}"
+ GETOS="${GETYA}\n${GET2}\n${GET3}\n${GET4}\n${GET5}\n${GET6}"
+ ;;
+ 7)
+ BOOTVARS="${BTYA}\n${BT2}\n${BT3}\n${BT4}\n${BT5}\n${BT6}\n${BT7}"
+ MENUOPTS="${MENUYA}\n${MENU2}\n${MENU3}\n${MENU4}\n${MENU5}\n${MENU6}\n${MENU7}"
+ GETOS="${GETYA}\n${GET2}\n${GET3}\n${GET4}\n${GET5}\n${GET6}\n${GET7}"
+ ;;
+ 8)
+ BOOTVARS="${BTYA}\n${BT2}\n${BT3}\n${BT4}\n${BT5}\n${BT6}\n${BT7}\n${BT8}"
+ MENUOPTS="${MENUYA}\n${MENU2}\n${MENU3}\n${MENU4}\n${MENU5}\n${MENU6}\n${MENU7}\n${MENU8}"
+ GETOS="${GETYA}\n${GET2}\n${GET3}\n${GET4}\n${GET5}\n${GET6}\n${GET7}\n${GET8}"
+ ;;
+esac
+
+if [ -n "$YBINOFICON" -a -f "$YBINOFICON" -a -r "$YBINOFICON" ] ; then
+ OFBOOTICON="$(cat "$YBINOFICON")"
+else
+ OFBOOTICON="<OS-BADGE-ICONS>
+1010
+000000000000F8FEACF6000000000000
+0000000000F5FFFFFEFEF50000000000
+00000000002BFAFEFAFCF70000000000
+0000000000F65D5857812B0000000000
+0000000000F5350B2F88560000000000
+0000000000F6335708F8FE0000000000
+00000000005600F600F5FD8100000000
+00000000F9F8000000F5FAFFF8000000
+000000008100F5F50000F6FEFE000000
+000000F8F700F500F50000FCFFF70000
+00000088F70000F50000F5FCFF2B0000
+0000002F582A00F5000008ADE02C0000
+00090B0A35A62B0000002D3B350A0000
+000A0A0B0B3BF60000505E0B0A0B0A00
+002E350B0B2F87FAFCF45F0B2E090000
+00000007335FF82BF72B575907000000
+000000000000ACFFFF81000000000000
+000000000081FFFFFFFF810000000000
+0000000000FBFFFFFFFFAC0000000000
+000000000081DFDFDFFFFB0000000000
+000000000081DD5F83FFFD0000000000
+000000000081DDDF5EACFF0000000000
+0000000000FDF981F981FFFF00000000
+00000000FFACF9F9F981FFFFAC000000
+00000000FFF98181F9F981FFFF000000
+000000ACACF981F981F9F9FFFFAC0000
+000000FFACF9F981F9F981FFFFFB0000
+00000083DFFBF981F9F95EFFFFFC0000
+005F5F5FDDFFFBF9F9F983DDDD5F0000
+005F5F5F5FDD81F9F9E7DF5F5F5F5F00
+0083DD5F5F83FFFFFFFFDF5F835F0000
+000000FBDDDFACFBACFBDFDFFB000000
+000000000000FFFFFFFF000000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFFFF00000000
+00000000FFFFFFFFFFFFFFFFFF000000
+00000000FFFFFFFFFFFFFFFFFF000000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+00FFFFFFFFFFFFFFFFFFFFFFFFFF0000
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00FFFFFFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFF000000
+</OS-BADGE-ICONS>"
+fi
+
+## create tmp files safely.
+TMP="${TMPDIR:-/tmp}"
+TMPBOOT=`mktemp -q "$TMP/ofboot.XXXXXX"`
+ if [ $? != 0 ] ; then
+ echo 1>&2 "Cannot create temp file, aborting."
+ exit 1
+ fi
+
+## create the real script
+$PRINTF \
+"<CHRP-BOOT>
+<COMPATIBLE>
+MacRISC
+</COMPATIBLE>
+<DESCRIPTION>
+PowerPC GNU/Linux First Stage Bootstrap
+</DESCRIPTION>
+<BOOT-SCRIPT>
+: .printf fb8-write drop ;
+$BOOTVARS
+\" screen\" output
+variable interactive
+$MENU interactive !
+
+0 interactive @ = if
+ bootyaboot
+then
+
+dev screen
+\" \"(0000000000aa00aa0000aaaaaa0000aa00aaaa5500aaaaaa)\" drop 0 7 set-colors
+\" \"(5555555555ff55ff5555ffffff5555ff55ffffff55ffffff)\" drop 8 15 set-colors
+device-end
+$FGCOLOR to foreground-color
+$BGCOLOR to background-color
+\" \"(0C)\" .printf
+
+\" First Stage GNU/Linux Bootstrap\"(0d 0a)\" .printf
+\" \"(0d 0a)\" .printf
+$MENUOPTS
+\" \"(0d 0a)\" .printf
+\" Boot: \" .printf
+get-msecs d# $TIMEOUT 3E8 * +
+begin
+ key? if
+ key case
+$GETOS
+ endcase
+ then
+ dup get-msecs <
+until
+drop
+\" \"(0d 0a)\" .printf $DEFAULTOS
+</BOOT-SCRIPT>
+$OFBOOTICON
+</CHRP-BOOT>\n" > "$TMPBOOT"
+
+echo "$TMPBOOT"
--- /dev/null
+#ifndef __PPC_ELF_H
+#define __PPC_ELF_H
+
+#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
+#define ELF_NFPREG 33 /* includes fpscr */
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x) == EM_PPC)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_ARCH EM_PPC
+#define ELF_CLASS ELFCLASS32
+#define ELF_DATA ELFDATA2MSB
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 4096
+
+/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
+ use of this is to invoke "./ld.so someprog" to test out a new version of
+ the loader. We need to make sure that it is out of the way of the program
+ that it will "exec", and that there is sufficient room for the brk. */
+
+#define ELF_ET_DYN_BASE (0x08000000)
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+#define ELF_CORE_COPY_REGS(gregs, regs) \
+ memcpy(gregs, regs, \
+ sizeof(struct pt_regs) < sizeof(elf_gregset_t)? \
+ sizeof(struct pt_regs): sizeof(elf_gregset_t));
+
+
+/* This yields a mask that user programs can use to figure out what
+ instruction set this cpu supports. This could be done in userspace,
+ but it's not easy, and we've already done it here. */
+
+#define ELF_HWCAP (0)
+
+/* This yields a string that ld.so will use to load implementation
+ specific libraries for optimization. This is more specific in
+ intent than poking at uname or /proc/cpuinfo.
+
+ For the moment, we have only optimizations for the Intel generations,
+ but that could change... */
+
+#define ELF_PLATFORM (NULL)
+
+
+#endif
--- /dev/null
+/* Register names */
+#define r0 0
+#define r1 1
+#define r2 2
+#define r3 3
+#define r4 4
+#define r5 5
+#define r6 6
+#define r7 7
+#define r8 8
+#define r9 9
+#define r10 10
+#define r11 11
+#define r12 12
+#define r13 13
+#define r14 14
+#define r15 15
+#define r16 16
+#define r17 17
+#define r18 18
+#define r19 19
+#define r20 20
+#define r21 21
+#define r22 22
+#define r23 23
+#define r24 24
+#define r25 25
+#define r26 26
+#define r27 27
+#define r28 28
+#define r29 29
+#define r30 30
+#define r31 31
+
+#define fr0 0
+#define fr1 1
+#define fr2 2
+#define fr3 3
+#define fr4 4
+#define fr5 5
+#define fr6 6
+#define fr7 7
+#define fr8 8
+#define fr9 9
+#define fr10 10
+#define fr11 11
+#define fr12 12
+#define fr13 13
+#define fr14 14
+#define fr15 15
+#define fr16 16
+#define fr17 17
+#define fr18 18
+#define fr19 19
+#define fr20 20
+#define fr21 21
+#define fr22 22
+#define fr23 23
+#define fr24 24
+#define fr25 25
+#define fr26 26
+#define fr27 27
+#define fr28 28
+#define fr29 29
+#define fr30 30
+#define fr31 31
--- /dev/null
+#ifndef __ASM_PPC_PROCESSOR_H
+#define __ASM_PPC_PROCESSOR_H
+
+/* Bit encodings for Machine State Register (MSR) */
+#define MSR_POW (1<<18) /* Enable Power Management */
+#define MSR_TGPR (1<<17) /* TLB Update registers in use */
+#define MSR_ILE (1<<16) /* Interrupt Little-Endian enable */
+#define MSR_EE (1<<15) /* External Interrupt enable */
+#define MSR_PR (1<<14) /* Supervisor/User privilege */
+#define MSR_FP (1<<13) /* Floating Point enable */
+#define MSR_ME (1<<12) /* Machine Check enable */
+#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */
+#define MSR_SE (1<<10) /* Single Step */
+#define MSR_BE (1<<9) /* Branch Trace */
+#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */
+#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */
+#define MSR_IR (1<<5) /* Instruction MMU enable */
+#define MSR_DR (1<<4) /* Data MMU enable */
+#define MSR_RI (1<<1) /* Recoverable Exception */
+#define MSR_LE (1<<0) /* Little-Endian enable */
+
+/* Bit encodings for Hardware Implementation Register (HID0)
+ on PowerPC 603, 604, etc. processors (not 601). */
+#define HID0_EMCP (1<<31) /* Enable Machine Check pin */
+#define HID0_EBA (1<<29) /* Enable Bus Address Parity */
+#define HID0_EBD (1<<28) /* Enable Bus Data Parity */
+#define HID0_SBCLK (1<<27)
+#define HID0_EICE (1<<26)
+#define HID0_ECLK (1<<25)
+#define HID0_PAR (1<<24)
+#define HID0_DOZE (1<<23)
+#define HID0_NAP (1<<22)
+#define HID0_SLEEP (1<<21)
+#define HID0_DPM (1<<20)
+#define HID0_ICE (1<<15) /* Instruction Cache Enable */
+#define HID0_DCE (1<<14) /* Data Cache Enable */
+#define HID0_ILOCK (1<<13) /* Instruction Cache Lock */
+#define HID0_DLOCK (1<<12) /* Data Cache Lock */
+#define HID0_ICFI (1<<11) /* Instruction Cache Flash Invalidate */
+#define HID0_DCI (1<<10) /* Data Cache Invalidate */
+#define HID0_SPD (1<<9) /* Speculative disable */
+#define HID0_SIED (1<<7) /* Serial Instruction Execution [Disable] */
+#define HID0_BHTE (1<<2) /* Branch History Table Enable */
+#define HID0_BTCD (1<<1) /* Branch target cache disable */
+
+/* fpscr settings */
+#define FPSCR_FX (1<<31)
+#define FPSCR_FEX (1<<30)
+
+#define _GLOBAL(n)\
+ .globl n;\
+n:
+
+#define TBRU 269 /* Time base Upper/Lower (Reading) */
+#define TBRL 268
+#define TBWU 284 /* Time base Upper/Lower (Writing) */
+#define TBWL 285
+#define XER 1
+#define LR 8
+#define CTR 9
+#define HID0 1008 /* Hardware Implementation */
+#define PVR 287 /* Processor Version */
+#define IBAT0U 528 /* Instruction BAT #0 Upper/Lower */
+#define IBAT0L 529
+#define IBAT1U 530 /* Instruction BAT #1 Upper/Lower */
+#define IBAT1L 531
+#define IBAT2U 532 /* Instruction BAT #2 Upper/Lower */
+#define IBAT2L 533
+#define IBAT3U 534 /* Instruction BAT #3 Upper/Lower */
+#define IBAT3L 535
+#define DBAT0U 536 /* Data BAT #0 Upper/Lower */
+#define DBAT0L 537
+#define DBAT1U 538 /* Data BAT #1 Upper/Lower */
+#define DBAT1L 539
+#define DBAT2U 540 /* Data BAT #2 Upper/Lower */
+#define DBAT2L 541
+#define DBAT3U 542 /* Data BAT #3 Upper/Lower */
+#define DBAT3L 543
+#define DMISS 976 /* TLB Lookup/Refresh registers */
+#define DCMP 977
+#define HASH1 978
+#define HASH2 979
+#define IMISS 980
+#define ICMP 981
+#define RPA 982
+#define SDR1 25 /* MMU hash base register */
+#define DAR 19 /* Data Address Register */
+#define SPR0 272 /* Supervisor Private Registers */
+#define SPRG0 272
+#define SPR1 273
+#define SPRG1 273
+#define SPR2 274
+#define SPRG2 274
+#define SPR3 275
+#define SPRG3 275
+#define DSISR 18
+#define SRR0 26 /* Saved Registers (exception) */
+#define SRR1 27
+#define IABR 1010 /* Instruction Address Breakpoint */
+#define DEC 22 /* Decrementer */
+#define EAR 282 /* External Address Register */
+#define L2CR 1017 /* PPC 750 L2 control register */
+
+#define THRM1 1020
+#define THRM2 1021
+#define THRM3 1022
+#define THRM1_TIN 0x1
+#define THRM1_TIV 0x2
+#define THRM1_THRES (0x7f<<2)
+#define THRM1_TID (1<<29)
+#define THRM1_TIE (1<<30)
+#define THRM1_V (1<<31)
+#define THRM3_E (1<<31)
+
+/* Segment Registers */
+#define SR0 0
+#define SR1 1
+#define SR2 2
+#define SR3 3
+#define SR4 4
+#define SR5 5
+#define SR6 6
+#define SR7 7
+#define SR8 8
+#define SR9 9
+#define SR10 10
+#define SR11 11
+#define SR12 12
+#define SR13 13
+#define SR14 14
+#define SR15 15
+
+#ifndef __ASSEMBLY__
+static __inline__ unsigned long mfmsr(void)
+{
+ unsigned long msr;
+ __asm__ __volatile__("mfmsr %0" : "=r" (msr));
+ return msr;
+}
+#endif
+
+#endif /* __ASM_PPC_PROCESSOR_H */
--- /dev/null
+/*
+ * Non-machine dependent bootinfo structure. Basic idea
+ * borrowed from the m68k.
+ *
+ * Copyright (C) 1999 Cort Dougan <cort@ppc.kernel.org>
+ */
+
+
+#ifndef _PPC_BOOTINFO_H
+#define _PPC_BOOTINFO_H
+
+#define _MACH_prep 0x00000001
+#define _MACH_Pmac 0x00000002 /* pmac or pmac clone (non-chrp) */
+#define _MACH_chrp 0x00000004 /* chrp machine */
+#define _MACH_mbx 0x00000008 /* Motorola MBX board */
+#define _MACH_apus 0x00000010 /* amiga with phase5 powerup */
+#define _MACH_fads 0x00000020 /* Motorola FADS board */
+#define _MACH_rpxlite 0x00000040 /* RPCG RPX-Lite 8xx board */
+#define _MACH_bseip 0x00000080 /* Bright Star Engineering ip-Engine */
+#define _MACH_yk 0x00000100 /* Motorola Yellowknife */
+#define _MACH_gemini 0x00000200 /* Synergy Microsystems gemini board */
+#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 */
+
+struct bi_record {
+ unsigned long tag; /* tag ID */
+ unsigned long size; /* size of record (in bytes) */
+ unsigned long data[0]; /* data */
+};
+
+#define BI_FIRST 0x1010 /* first record - marker */
+#define BI_LAST 0x1011 /* last record - marker */
+#define BI_CMD_LINE 0x1012
+#define BI_BOOTLOADER_ID 0x1013
+#define BI_INITRD 0x1014
+#define BI_SYSMAP 0x1015
+#define BI_MACHTYPE 0x1016
+
+#endif /* _PPC_BOOTINFO_H */
+
--- /dev/null
+#ifndef _BYTEORDER_H_
+#define _BYTEORDER_H_
+
+#include "swab.h"
+
+# define le64_to_cpu(x) swab64((x))
+# define cpu_to_le64(x) swab64((x))
+# define le32_to_cpu(x) swab32((x))
+# define cpu_to_le32(x) swab32((x))
+# define le16_to_cpu(x) swab16((x))
+# define cpu_to_le16(x) swab16((x))
+
+#endif /* _BYTEORDER_H_ */
--- /dev/null
+/*
+ Config definitions
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef CFG_H
+#define CFG_H
+
+#include "types.h"
+
+extern int cfg_parse(char *cfg_file, char *buff, int len);
+extern char* cfg_get_strg(char *image, char *item);
+extern int cfg_get_flag(char *image, char *item);
+extern void cfg_print_images(void);
+extern char* cfg_get_default(void);
+
+#endif
--- /dev/null
+/*
+ Interface to command line
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef CMDLINE_H
+#define CMDLINE_H
+
+#include "types.h"
+
+extern void cmdinit();
+extern void cmdedit(void (*tabfunc) (void), int password);
+
+extern char cbuff[];
+extern char passwdbuff[];
+#endif
--- /dev/null
+#ifndef _LINUX_CTYPE_H
+#define _LINUX_CTYPE_H
+
+/*
+ * NOTE! This ctype does not handle EOF like the standard C
+ * library is required to.
+ */
+
+#define _U 0x01 /* upper */
+#define _L 0x02 /* lower */
+#define _D 0x04 /* digit */
+#define _C 0x08 /* cntrl */
+#define _P 0x10 /* punct */
+#define _S 0x20 /* white space (space/lf/tab) */
+#define _X 0x40 /* hex digit */
+#define _SP 0x80 /* hard space (0x20) */
+
+extern unsigned char _ctype[];
+
+#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
+
+#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
+#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
+#define iscntrl(c) ((__ismask(c)&(_C)) != 0)
+#define isdigit(c) ((__ismask(c)&(_D)) != 0)
+#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
+#define islower(c) ((__ismask(c)&(_L)) != 0)
+#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
+#define ispunct(c) ((__ismask(c)&(_P)) != 0)
+#define isspace(c) ((__ismask(c)&(_S)) != 0)
+#define isupper(c) ((__ismask(c)&(_U)) != 0)
+#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
+
+#define isascii(c) (((unsigned char)(c))<=0x7f)
+#define toascii(c) (((unsigned char)(c))&0x7f)
+
+static inline unsigned char __tolower(unsigned char c)
+{
+ if (isupper(c))
+ c -= 'A'-'a';
+ return c;
+}
+
+static inline unsigned char __toupper(unsigned char c)
+{
+ if (islower(c))
+ c -= 'a'-'A';
+ return c;
+}
+
+#define tolower(c) __tolower(c)
+#define toupper(c) __toupper(c)
+
+#endif
--- /dev/null
+/*
+ * Copyright 1987, 1988 by MIT Student Information Processing Board.
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose is hereby granted, provided that
+ * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. M.I.T. and the
+ * M.I.T. S.I.P.B. make no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+
+#include <stdio.h>
+#include "com_err.h"
+#include "error_table.h"
+#include "internal.h"
+
+#if !defined(__STDC__) && !defined(STDARG_PROTOTYPES)
+#include <varargs.h>
+#define VARARGS
+#endif
+
+static void
+#ifdef __STDC__
+ default_com_err_proc (const char *whoami, errcode_t code, const
+ char *fmt, va_list args)
+#else
+ default_com_err_proc (whoami, code, fmt, args)
+ const char *whoami;
+ errcode_t code;
+ const char *fmt;
+ va_list args;
+#endif
+{
+ if (whoami) {
+ fputs(whoami, stderr);
+ fputs(": ", stderr);
+ }
+ if (code) {
+ fputs(error_message(code), stderr);
+ fputs(" ", stderr);
+ }
+ if (fmt) {
+ vfprintf (stderr, fmt, args);
+ }
+ /* should do this only on a tty in raw mode */
+ putc('\r', stderr);
+ putc('\n', stderr);
+ fflush(stderr);
+}
+
+#ifdef __STDC__
+typedef void (*errf) (const char *, errcode_t, const char *, va_list);
+#else
+typedef void (*errf) ();
+#endif
+
+errf com_err_hook = default_com_err_proc;
+
+#ifdef __STDC__
+void com_err_va (const char *whoami, errcode_t code, const char *fmt,
+ va_list args)
+#else
+void com_err_va (whoami, code, fmt, args)
+ const char *whoami;
+ errcode_t code;
+ const char *fmt;
+ va_list args;
+#endif
+{
+ (*com_err_hook) (whoami, code, fmt, args);
+}
+
+#ifndef VARARGS
+void com_err (const char *whoami,
+ errcode_t code,
+ const char *fmt, ...)
+{
+#else
+void com_err (va_alist)
+ va_dcl
+{
+ const char *whoami, *fmt;
+ errcode_t code;
+#endif
+ va_list pvar;
+
+ if (!com_err_hook)
+ com_err_hook = default_com_err_proc;
+#ifdef VARARGS
+ va_start (pvar);
+ whoami = va_arg (pvar, const char *);
+ code = va_arg (pvar, errcode_t);
+ fmt = va_arg (pvar, const char *);
+#else
+ va_start(pvar, fmt);
+#endif
+ com_err_va (whoami, code, fmt, pvar);
+ va_end(pvar);
+}
+
+errf set_com_err_hook (new_proc)
+ errf new_proc;
+{
+ errf x = com_err_hook;
+
+ if (new_proc)
+ com_err_hook = new_proc;
+ else
+ com_err_hook = default_com_err_proc;
+
+ return x;
+}
+
+errf reset_com_err_hook () {
+ errf x = com_err_hook;
+ com_err_hook = default_com_err_proc;
+ return x;
+}
--- /dev/null
+/*
+ * Header file for common error description library.
+ *
+ * Copyright 1988, Student Information Processing Board of the
+ * Massachusetts Institute of Technology.
+ *
+ * For copyright and distribution info, see the documentation supplied
+ * with this package.
+ */
+
+#ifndef __COM_ERR_H
+
+typedef long errcode_t;
+
+#ifdef __STDC__
+#include <stdarg.h>
+
+/* ANSI C -- use prototypes etc */
+void com_err (const char *, long, const char *, ...);
+void com_err_va (const char *whoami, errcode_t code, const char *fmt,
+ va_list args);
+char const *error_message (long);
+extern void (*com_err_hook) (const char *, long, const char *, va_list);
+void (*set_com_err_hook (void (*) (const char *, long, const char *, va_list)))
+ (const char *, long, const char *, va_list);
+void (*reset_com_err_hook (void)) (const char *, long, const char *, va_list);
+int init_error_table(const char * const *msgs, int base, int count);
+#else
+/* no prototypes */
+void com_err ();
+void com_err_va ();
+char *error_message ();
+extern void (*com_err_hook) ();
+void (*set_com_err_hook ()) ();
+void (*reset_com_err_hook ()) ();
+int init_error_table();
+#endif
+
+#define __COM_ERR_H
+#endif /* ! defined(__COM_ERR_H) */
--- /dev/null
+/*
+ * bitops.h --- Bitmap frobbing code. The byte swapping routines are
+ * also included here.
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ *
+ * i386 bitops operations taken from <asm/bitops.h>, Copyright 1992,
+ * Linus Torvalds.
+ */
+
+
+extern int ext2fs_set_bit(int nr,void * addr);
+extern int ext2fs_clear_bit(int nr, void * addr);
+extern int ext2fs_test_bit(int nr, const void * addr);
+extern __u16 ext2fs_swab16(__u16 val);
+extern __u32 ext2fs_swab32(__u32 val);
+
+/*
+ * EXT2FS bitmap manipulation routines.
+ */
+
+/* Support for sending warning messages from the inline subroutines */
+extern const char *ext2fs_block_string;
+extern const char *ext2fs_inode_string;
+extern const char *ext2fs_mark_string;
+extern const char *ext2fs_unmark_string;
+extern const char *ext2fs_test_string;
+extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
+ const char *description);
+extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+ int code, unsigned long arg);
+
+extern void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
+extern void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block);
+extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
+
+extern void ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ino_t inode);
+extern void ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ino_t inode);
+extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ino_t inode);
+
+extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block);
+extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block);
+extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block);
+
+extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ino_t inode);
+extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ino_t inode);
+extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ino_t inode);
+extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
+extern ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
+extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
+extern ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
+
+extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num);
+extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
+
+/*
+ * The inline routines themselves...
+ *
+ * If NO_INLINE_FUNCS is defined, then we won't try to do inline
+ * functions at all; they will be included as normal functions in
+ * inline.c
+ */
+#ifdef NO_INLINE_FUNCS
+#if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \
+ defined(__i586__) || defined(__mc68000__) || \
+ defined(__sparc__)))
+ /* This prevents bitops.c from trying to include the C */
+ /* function version of these functions */
+#define _EXT2_HAVE_ASM_BITOPS_
+#endif
+#endif /* NO_INLINE_FUNCS */
+
+#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
+#ifdef INCLUDE_INLINE_FUNCS
+#define _INLINE_ extern
+#else
+#ifdef __GNUC__
+#define _INLINE_ extern __inline__
+#else /* For Watcom C */
+#define _INLINE_ extern inline
+#endif
+#endif
+
+#if ((defined __GNUC__) && (defined(__i386__) || defined(__i486__) || \
+ defined(__i586__)))
+
+#define _EXT2_HAVE_ASM_BITOPS_
+
+/*
+ * These are done by inline assembly for speed reasons.....
+ *
+ * All bitoperations return 0 if the bit was cleared before the
+ * operation and != 0 if it was not. Bit 0 is the LSB of addr; bit 32
+ * is the LSB of (addr+1).
+ */
+
+/*
+ * Some hacks to defeat gcc over-optimizations..
+ */
+struct __dummy_h { unsigned long a[100]; };
+#define EXT2FS_ADDR (*(struct __dummy_h *) addr)
+#define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)
+
+_INLINE_ int ext2fs_set_bit(int nr, void * addr)
+{
+ int oldbit;
+
+ __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit),"=m" (EXT2FS_ADDR)
+ :"r" (nr));
+ return oldbit;
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+ int oldbit;
+
+ __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit),"=m" (EXT2FS_ADDR)
+ :"r" (nr));
+ return oldbit;
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+ int oldbit;
+
+ __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit)
+ :"m" (EXT2FS_CONST_ADDR),"r" (nr));
+ return oldbit;
+}
+
+#undef EXT2FS_ADDR
+
+#endif /* i386 */
+
+#ifdef __mc68000__
+
+#define _EXT2_HAVE_ASM_BITOPS_
+
+_INLINE_ int ext2fs_set_bit(int nr,void * addr)
+{
+ char retval;
+
+ __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
+ : "=d" (retval) : "d" (nr^7), "a" (addr));
+
+ return retval;
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+ char retval;
+
+ __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
+ : "=d" (retval) : "d" (nr^7), "a" (addr));
+
+ return retval;
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+ char retval;
+
+ __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
+ : "=d" (retval) : "d" (nr^7), "a" (addr));
+
+ return retval;
+}
+
+#endif /* __mc68000__ */
+
+#ifdef __sparc__
+
+#define _EXT2_HAVE_ASM_BITOPS_
+
+#ifndef EXT2_OLD_BITOPS
+
+/*
+ * Do the bitops so that we are compatible with the standard i386
+ * convention.
+ */
+
+_INLINE_ int ext2fs_set_bit(int nr,void * addr)
+{
+#if 1
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("ldub [%0], %%g6\n\t"
+ "or %%g6, %2, %%g5\n\t"
+ "stb %%g5, [%0]\n\t"
+ "and %%g6, %2, %0\n"
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g5", "g6");
+ return (int) ADDR;
+#else
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ retval = (mask & *ADDR) != 0;
+ *ADDR |= mask;
+ return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+#if 1
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("ldub [%0], %%g6\n\t"
+ "andn %%g6, %2, %%g5\n\t"
+ "stb %%g5, [%0]\n\t"
+ "and %%g6, %2, %0\n"
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g5", "g6");
+ return (int) ADDR;
+
+#else
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ retval = (mask & *ADDR) != 0;
+ *ADDR &= ~mask;
+ return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+ int mask;
+ const unsigned char *ADDR = (const unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ return ((mask & *ADDR) != 0);
+}
+
+#else
+
+/* Do things the old, unplesant way. */
+
+_INLINE_ int ext2fs_set_bit(int nr, void *addr)
+{
+ int mask, retval;
+ unsigned long *ADDR = (unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ retval = ((mask & *ADDR) != 0);
+ *ADDR |= mask;
+ return retval;
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void *addr)
+{
+ int mask, retval;
+ unsigned long *ADDR = (unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ retval = ((mask & *ADDR) != 0);
+ *ADDR &= ~mask;
+ return retval;
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void *addr)
+{
+ int mask;
+ const unsigned long *ADDR = (const unsigned long *) addr;
+
+ ADDR += nr >> 5;
+ mask = 1 << (nr & 31);
+ return ((mask & *ADDR) != 0);
+}
+#endif
+
+#endif /* __sparc__ */
+
+#ifndef _EXT2_HAVE_ASM_SWAB
+
+_INLINE_ __u16 ext2fs_swab16(__u16 val)
+{
+ return (val >> 8) | (val << 8);
+}
+
+_INLINE_ __u32 ext2fs_swab32(__u32 val)
+{
+ return ((val>>24) | ((val>>8)&0xFF00) |
+ ((val<<8)&0xFF0000) | (val<<24));
+}
+
+#endif /* !_EXT2_HAVE_ASM_SWAB */
+
+_INLINE_ void ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ __u32 bitno);
+_INLINE_ void ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno);
+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno);
+
+_INLINE_ void ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ __u32 bitno)
+{
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
+ return;
+ }
+ ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno)
+{
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
+ return;
+ }
+ ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno)
+{
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
+ return 0;
+ }
+ return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+ ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
+}
+
+_INLINE_ void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+ ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
+}
+
+_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+ return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ block);
+}
+
+_INLINE_ void ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ino_t inode)
+{
+ ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
+}
+
+_INLINE_ void ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ino_t inode)
+{
+ ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
+}
+
+_INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ino_t inode)
+{
+ return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ inode);
+}
+
+_INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
+ bitmap->description);
+ return;
+ }
+#endif
+ ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
+ block, bitmap->description);
+ return;
+ }
+#endif
+ ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
+ block, bitmap->description);
+ return 0;
+ }
+#endif
+ return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ino_t inode)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((inode < bitmap->start) || (inode > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
+ inode, bitmap->description);
+ return;
+ }
+#endif
+ ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ino_t inode)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((inode < bitmap->start) || (inode > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
+ inode, bitmap->description);
+ return;
+ }
+#endif
+ ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
+ ino_t inode)
+{
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((inode < bitmap->start) || (inode > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
+ inode, bitmap->description);
+ return 0;
+ }
+#endif
+ return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
+{
+ return bitmap->start;
+}
+
+_INLINE_ ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
+{
+ return bitmap->start;
+}
+
+_INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
+{
+ return bitmap->end;
+}
+
+_INLINE_ ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
+{
+ return bitmap->end;
+}
+
+_INLINE_ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
+ block, bitmap->description);
+ return 0;
+ }
+ for (i=0; i < num; i++) {
+ if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
+ return 0;
+ }
+ return 1;
+}
+
+_INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
+ block, bitmap->description);
+ return 0;
+ }
+#endif
+ for (i=0; i < num; i++) {
+ if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
+ return 0;
+ }
+ return 1;
+}
+
+_INLINE_ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
+ bitmap->description);
+ return;
+ }
+ for (i=0; i < num; i++)
+ ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
+ bitmap->description);
+ return;
+ }
+#endif
+ for (i=0; i < num; i++)
+ ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
+ bitmap->description);
+ return;
+ }
+ for (i=0; i < num; i++)
+ ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+#ifdef EXT2FS_DEBUG_FAST_OPS
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
+ bitmap->description);
+ return;
+ }
+#endif
+ for (i=0; i < num; i++)
+ ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+#undef _INLINE_
+#endif
+
--- /dev/null
+/*
+ * ext2_err.h:
+ * This file is automatically generated; please do not edit it.
+ */
+
+#define EXT2_ET_BASE (2133571328L)
+#define EXT2_ET_MAGIC_EXT2FS_FILSYS (2133571329L)
+#define EXT2_ET_MAGIC_BADBLOCKS_LIST (2133571330L)
+#define EXT2_ET_MAGIC_BADBLOCKS_ITERATE (2133571331L)
+#define EXT2_ET_MAGIC_INODE_SCAN (2133571332L)
+#define EXT2_ET_MAGIC_IO_CHANNEL (2133571333L)
+#define EXT2_ET_MAGIC_UNIX_IO_CHANNEL (2133571334L)
+#define EXT2_ET_MAGIC_IO_MANAGER (2133571335L)
+#define EXT2_ET_MAGIC_BLOCK_BITMAP (2133571336L)
+#define EXT2_ET_MAGIC_INODE_BITMAP (2133571337L)
+#define EXT2_ET_MAGIC_GENERIC_BITMAP (2133571338L)
+#define EXT2_ET_MAGIC_TEST_IO_CHANNEL (2133571339L)
+#define EXT2_ET_MAGIC_DBLIST (2133571340L)
+#define EXT2_ET_MAGIC_ICOUNT (2133571341L)
+#define EXT2_ET_MAGIC_PQ_IO_CHANNEL (2133571342L)
+#define EXT2_ET_MAGIC_EXT2_FILE (2133571343L)
+#define EXT2_ET_MAGIC_RESERVED_7 (2133571344L)
+#define EXT2_ET_MAGIC_RESERVED_8 (2133571345L)
+#define EXT2_ET_MAGIC_RESERVED_9 (2133571346L)
+#define EXT2_ET_BAD_MAGIC (2133571347L)
+#define EXT2_ET_REV_TOO_HIGH (2133571348L)
+#define EXT2_ET_RO_FILSYS (2133571349L)
+#define EXT2_ET_GDESC_READ (2133571350L)
+#define EXT2_ET_GDESC_WRITE (2133571351L)
+#define EXT2_ET_GDESC_BAD_BLOCK_MAP (2133571352L)
+#define EXT2_ET_GDESC_BAD_INODE_MAP (2133571353L)
+#define EXT2_ET_GDESC_BAD_INODE_TABLE (2133571354L)
+#define EXT2_ET_INODE_BITMAP_WRITE (2133571355L)
+#define EXT2_ET_INODE_BITMAP_READ (2133571356L)
+#define EXT2_ET_BLOCK_BITMAP_WRITE (2133571357L)
+#define EXT2_ET_BLOCK_BITMAP_READ (2133571358L)
+#define EXT2_ET_INODE_TABLE_WRITE (2133571359L)
+#define EXT2_ET_INODE_TABLE_READ (2133571360L)
+#define EXT2_ET_NEXT_INODE_READ (2133571361L)
+#define EXT2_ET_UNEXPECTED_BLOCK_SIZE (2133571362L)
+#define EXT2_ET_DIR_CORRUPTED (2133571363L)
+#define EXT2_ET_SHORT_READ (2133571364L)
+#define EXT2_ET_SHORT_WRITE (2133571365L)
+#define EXT2_ET_DIR_NO_SPACE (2133571366L)
+#define EXT2_ET_NO_INODE_BITMAP (2133571367L)
+#define EXT2_ET_NO_BLOCK_BITMAP (2133571368L)
+#define EXT2_ET_BAD_INODE_NUM (2133571369L)
+#define EXT2_ET_BAD_BLOCK_NUM (2133571370L)
+#define EXT2_ET_EXPAND_DIR_ERR (2133571371L)
+#define EXT2_ET_TOOSMALL (2133571372L)
+#define EXT2_ET_BAD_BLOCK_MARK (2133571373L)
+#define EXT2_ET_BAD_BLOCK_UNMARK (2133571374L)
+#define EXT2_ET_BAD_BLOCK_TEST (2133571375L)
+#define EXT2_ET_BAD_INODE_MARK (2133571376L)
+#define EXT2_ET_BAD_INODE_UNMARK (2133571377L)
+#define EXT2_ET_BAD_INODE_TEST (2133571378L)
+#define EXT2_ET_FUDGE_BLOCK_BITMAP_END (2133571379L)
+#define EXT2_ET_FUDGE_INODE_BITMAP_END (2133571380L)
+#define EXT2_ET_BAD_IND_BLOCK (2133571381L)
+#define EXT2_ET_BAD_DIND_BLOCK (2133571382L)
+#define EXT2_ET_BAD_TIND_BLOCK (2133571383L)
+#define EXT2_ET_NEQ_BLOCK_BITMAP (2133571384L)
+#define EXT2_ET_NEQ_INODE_BITMAP (2133571385L)
+#define EXT2_ET_BAD_DEVICE_NAME (2133571386L)
+#define EXT2_ET_MISSING_INODE_TABLE (2133571387L)
+#define EXT2_ET_CORRUPT_SUPERBLOCK (2133571388L)
+#define EXT2_ET_BAD_GENERIC_MARK (2133571389L)
+#define EXT2_ET_BAD_GENERIC_UNMARK (2133571390L)
+#define EXT2_ET_BAD_GENERIC_TEST (2133571391L)
+#define EXT2_ET_SYMLINK_LOOP (2133571392L)
+#define EXT2_ET_CALLBACK_NOTHANDLED (2133571393L)
+#define EXT2_ET_BAD_BLOCK_IN_INODE_TABLE (2133571394L)
+#define EXT2_ET_UNSUPP_FEATURE (2133571395L)
+#define EXT2_ET_RO_UNSUPP_FEATURE (2133571396L)
+#define EXT2_ET_LLSEEK_FAILED (2133571397L)
+#define EXT2_ET_NO_MEMORY (2133571398L)
+#define EXT2_ET_INVALID_ARGUMENT (2133571399L)
+#define EXT2_ET_BLOCK_ALLOC_FAIL (2133571400L)
+#define EXT2_ET_INODE_ALLOC_FAIL (2133571401L)
+#define EXT2_ET_NO_DIRECTORY (2133571402L)
+#define EXT2_ET_TOO_MANY_REFS (2133571403L)
+#define EXT2_ET_FILE_NOT_FOUND (2133571404L)
+#define EXT2_ET_FILE_RO (2133571405L)
+#define EXT2_ET_DB_NOT_FOUND (2133571406L)
+#define EXT2_ET_DIR_EXISTS (2133571407L)
+#define EXT2_ET_UNIMPLEMENTED (2133571408L)
+#define EXT2_ET_CANCEL_REQUESTED (2133571409L)
+#define EXT2_ET_FILE_TOO_BIG (2133571410L)
+extern void initialize_ext2_error_table(void);
+#define ERROR_TABLE_BASE_ext2 (2133571328L)
+
+/* for compatibility with older versions... */
+#define init_ext2_err_tbl initialize_ext2_error_table
+#define ext2_err_base ERROR_TABLE_BASE_ext2
--- /dev/null
+/*
+ * io.h --- the I/O manager abstraction
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#ifndef _EXT2FS_EXT2_IO_H
+#define _EXT2FS_EXT2_IO_H
+
+/*
+ * ext2_loff_t is defined here since unix_io.c needs it.
+ */
+#if defined(__GNUC__) || defined(HAS_LONG_LONG)
+typedef long long ext2_loff_t;
+#else
+typedef long ext2_loff_t;
+#endif
+
+/* llseek.c */
+ext2_loff_t ext2fs_llseek (int, ext2_loff_t, int);
+
+typedef struct struct_io_manager *io_manager;
+typedef struct struct_io_channel *io_channel;
+
+struct struct_io_channel {
+ errcode_t magic;
+ io_manager manager;
+ char *name;
+ int block_size;
+ errcode_t (*read_error)(io_channel channel,
+ unsigned long block,
+ int count,
+ void *data,
+ size_t size,
+ int actual_bytes_read,
+ errcode_t error);
+ errcode_t (*write_error)(io_channel channel,
+ unsigned long block,
+ int count,
+ const void *data,
+ size_t size,
+ int actual_bytes_written,
+ errcode_t error);
+ int refcount;
+ int reserved[15];
+ void *private_data;
+ void *app_data;
+};
+
+struct struct_io_manager {
+ errcode_t magic;
+ const char *name;
+ errcode_t (*open)(const char *name, int flags, io_channel *channel);
+ errcode_t (*close)(io_channel channel);
+ errcode_t (*set_blksize)(io_channel channel, int blksize);
+ errcode_t (*read_blk)(io_channel channel, unsigned long block,
+ int count, void *data);
+ errcode_t (*write_blk)(io_channel channel, unsigned long block,
+ int count, const void *data);
+ errcode_t (*flush)(io_channel channel);
+ int reserved[16];
+};
+
+#define IO_FLAG_RW 1
+
+/*
+ * Convenience functions....
+ */
+#define io_channel_close(c) ((c)->manager->close((c)))
+#define io_channel_set_blksize(c,s) ((c)->manager->set_blksize((c),s))
+#define io_channel_read_blk(c,b,n,d) ((c)->manager->read_blk((c),b,n,d))
+#define io_channel_write_blk(c,b,n,d) ((c)->manager->write_blk((c),b,n,d))
+#define io_channel_flush(c) ((c)->manager->flush((c)))
+#define io_channel_bumpcount(c) ((c)->refcount++)
+
+/* unix_io.c */
+extern io_manager unix_io_manager;
+
+/* test_io.c */
+extern io_manager test_io_manager, test_io_backing_manager;
+extern void (*test_io_cb_read_blk)
+ (unsigned long block, int count, errcode_t err);
+extern void (*test_io_cb_write_blk)
+ (unsigned long block, int count, errcode_t err);
+extern void (*test_io_cb_set_blksize)
+ (int blksize, errcode_t err);
+
+#endif /* _EXT2FS_EXT2_IO_H */
+
--- /dev/null
+/*
+ * ext2fs.h --- ext2fs
+ *
+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#ifndef _EXT2FS_EXT2FS_H
+#define _EXT2FS_EXT2FS_H
+
+/*
+ * Non-GNU C compilers won't necessarily understand inline
+ */
+#if (!defined(__GNUC__) && !defined(__WATCOMC__))
+#define NO_INLINE_FUNCS
+#endif
+
+/*
+ * Where the master copy of the superblock is located, and how big
+ * superblocks are supposed to be. We define SUPERBLOCK_SIZE because
+ * the size of the superblock structure is not necessarily trustworthy
+ * (some versions have the padding set up so that the superblock is
+ * 1032 bytes long).
+ */
+#define SUPERBLOCK_OFFSET 1024
+#define SUPERBLOCK_SIZE 1024
+
+/*
+ * The last ext2fs revision level that this version of the library is
+ * able to support.
+ */
+#define EXT2_LIB_CURRENT_REV 0
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <stdlib.h>
+
+#if EXT2_FLAT_INCLUDES
+#include "e2_types.h"
+#else
+#include <types.h>
+#if defined(__GNUC__) && defined(__STRICT_ANSI__) && \
+ (((~0UL) == 0xffffffff) || defined(__i386__))
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+#endif
+
+typedef __u32 blk_t;
+typedef __u32 dgrp_t;
+typedef __u32 ext2_off_t;
+typedef __s64 e2_blkcnt_t;
+
+#if EXT2_FLAT_INCLUDES
+#include "com_err.h"
+#include "ext2_io.h"
+#include "ext2_err.h"
+#else
+#include "et/com_err.h"
+#include "ext2fs/ext2_io.h"
+#include "ext2fs/ext2_err.h"
+#endif
+
+/*
+ * Portability help for Microsoft Visual C++
+ */
+#ifdef _MSC_VER
+#define EXT2_QSORT_TYPE int __cdecl
+#else
+#define EXT2_QSORT_TYPE int
+#endif
+
+typedef struct struct_ext2_filsys *ext2_filsys;
+
+struct ext2fs_struct_generic_bitmap {
+ errcode_t magic;
+ ext2_filsys fs;
+ __u32 start, end;
+ __u32 real_end;
+ char * description;
+ char * bitmap;
+ errcode_t base_error_code;
+ __u32 reserved[7];
+};
+
+#define EXT2FS_MARK_ERROR 0
+#define EXT2FS_UNMARK_ERROR 1
+#define EXT2FS_TEST_ERROR 2
+
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
+
+#ifdef EXT2_DYNAMIC_REV
+#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO(s)
+#else
+#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO
+#define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
+#endif
+
+/*
+ * badblocks list definitions
+ */
+
+typedef struct ext2_struct_badblocks_list *ext2_badblocks_list;
+typedef struct ext2_struct_badblocks_iterate *ext2_badblocks_iterate;
+
+/* old */
+typedef struct ext2_struct_badblocks_list *badblocks_list;
+typedef struct ext2_struct_badblocks_iterate *badblocks_iterate;
+
+#define BADBLOCKS_FLAG_DIRTY 1
+
+/*
+ * ext2_dblist structure and abstractions (see dblist.c)
+ */
+struct ext2_db_entry {
+ ino_t ino;
+ blk_t blk;
+ int blockcnt;
+};
+
+typedef struct ext2_struct_dblist *ext2_dblist;
+
+#define DBLIST_ABORT 1
+
+/*
+ * ext2_fileio definitions
+ */
+
+#define EXT2_FILE_WRITE 0x0001
+#define EXT2_FILE_CREATE 0x0002
+
+#define EXT2_FILE_MASK 0x00FF
+
+#define EXT2_FILE_BUF_DIRTY 0x4000
+#define EXT2_FILE_BUF_VALID 0x2000
+
+typedef struct ext2_file *ext2_file_t;
+
+#define EXT2_SEEK_SET 0
+#define EXT2_SEEK_CUR 1
+#define EXT2_SEEK_END 2
+
+/*
+ * Flags for the ext2_filsys structure
+ */
+
+#define EXT2_FLAG_RW 0x01
+#define EXT2_FLAG_CHANGED 0x02
+#define EXT2_FLAG_DIRTY 0x04
+#define EXT2_FLAG_VALID 0x08
+#define EXT2_FLAG_IB_DIRTY 0x10
+#define EXT2_FLAG_BB_DIRTY 0x20
+#define EXT2_FLAG_SWAP_BYTES 0x40
+#define EXT2_FLAG_SWAP_BYTES_READ 0x80
+#define EXT2_FLAG_SWAP_BYTES_WRITE 0x100
+#define EXT2_FLAG_MASTER_SB_ONLY 0x200
+#define EXT2_FLAG_FORCE 0x400
+
+/*
+ * Special flag in the ext2 inode i_flag field that means that this is
+ * a new inode. (So that ext2_write_inode() can clear extra fields.)
+ */
+#define EXT2_NEW_INODE_FL 0x80000000
+
+struct struct_ext2_filsys {
+ errcode_t magic;
+ io_channel io;
+ int flags;
+ char * device_name;
+ struct ext2_super_block * super;
+ int blocksize;
+ int fragsize;
+ dgrp_t group_desc_count;
+ unsigned long desc_blocks;
+ struct ext2_group_desc * group_desc;
+ int inode_blocks_per_group;
+ ext2fs_inode_bitmap inode_map;
+ ext2fs_block_bitmap block_map;
+ errcode_t (*get_blocks)(ext2_filsys fs, ino_t ino, blk_t *blocks);
+ errcode_t (*check_directory)(ext2_filsys fs, ino_t ino);
+ errcode_t (*write_bitmaps)(ext2_filsys fs);
+ errcode_t (*read_inode)(ext2_filsys fs, ino_t ino,
+ struct ext2_inode *inode);
+ errcode_t (*write_inode)(ext2_filsys fs, ino_t ino,
+ struct ext2_inode *inode);
+ badblocks_list badblocks;
+ ext2_dblist dblist;
+ __u32 stride; /* for mke2fs */
+ /*
+ * Reserved for future expansion
+ */
+ __u32 reserved[11];
+
+ /*
+ * Reserved for the use of the calling application.
+ */
+ void * priv_data;
+
+ /*
+ * Inode cache
+ */
+ struct ext2_inode_cache *icache;
+};
+
+#if EXT2_FLAT_INCLUDES
+#include "e2_bitops.h"
+#else
+#include "ext2fs/bitops.h"
+#endif
+
+/*
+ * Return flags for the block iterator functions
+ */
+#define BLOCK_CHANGED 1
+#define BLOCK_ABORT 2
+#define BLOCK_ERROR 4
+
+/*
+ * Block interate flags
+ *
+ * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the interator
+ * function should be called on blocks where the block number is zero.
+ * This is used by ext2fs_expand_dir() to be able to add a new block
+ * to an inode. It can also be used for programs that want to be able
+ * to deal with files that contain "holes".
+ *
+ * BLOCK_FLAG_TRAVERSE indicates that the iterator function for the
+ * indirect, doubly indirect, etc. blocks should be called after all
+ * of the blocks containined in the indirect blocks are processed.
+ * This is useful if you are going to be deallocating blocks from an
+ * inode.
+ *
+ * BLOCK_FLAG_DATA_ONLY indicates that the iterator function should be
+ * called for data blocks only.
+ *
+ * BLOCK_FLAG_NO_LARGE is for internal use only. It informs
+ * ext2fs_block_iterate2 that large files won't be accepted.
+ */
+#define BLOCK_FLAG_APPEND 1
+#define BLOCK_FLAG_HOLE 1
+#define BLOCK_FLAG_DEPTH_TRAVERSE 2
+#define BLOCK_FLAG_DATA_ONLY 4
+
+#define BLOCK_FLAG_NO_LARGE 0x1000
+
+/*
+ * Magic "block count" return values for the block iterator function.
+ */
+#define BLOCK_COUNT_IND (-1)
+#define BLOCK_COUNT_DIND (-2)
+#define BLOCK_COUNT_TIND (-3)
+#define BLOCK_COUNT_TRANSLATOR (-4)
+
+#if 0
+/*
+ * Flags for ext2fs_move_blocks
+ */
+#define EXT2_BMOVE_GET_DBLIST 0x0001
+#define EXT2_BMOVE_DEBUG 0x0002
+#endif
+
+/*
+ * Return flags for the directory iterator functions
+ */
+#define DIRENT_CHANGED 1
+#define DIRENT_ABORT 2
+#define DIRENT_ERROR 3
+
+/*
+ * Directory iterator flags
+ */
+
+#define DIRENT_FLAG_INCLUDE_EMPTY 1
+
+
+#define DIRENT_DOT_FILE 1
+#define DIRENT_DOT_DOT_FILE 2
+#define DIRENT_OTHER_FILE 3
+
+/*
+ * Inode scan definitions
+ */
+typedef struct ext2_struct_inode_scan *ext2_inode_scan;
+
+/*
+ * ext2fs_scan flags
+ */
+#define EXT2_SF_CHK_BADBLOCKS 0x0001
+#define EXT2_SF_BAD_INODE_BLK 0x0002
+#define EXT2_SF_BAD_EXTRA_BYTES 0x0004
+#define EXT2_SF_SKIP_MISSING_ITABLE 0x0008
+
+/*
+ * ext2fs_check_if_mounted flags
+ */
+#define EXT2_MF_MOUNTED 1
+#define EXT2_MF_ISROOT 2
+#define EXT2_MF_READONLY 4
+
+/*
+ * Ext2/linux mode flags. We define them here so that we don't need
+ * to depend on the OS's sys/stat.h, since we may be compiling on a
+ * non-Linux system.
+ */
+#define LINUX_S_IFMT 00170000
+#define LINUX_S_IFSOCK 0140000
+#define LINUX_S_IFLNK 0120000
+#define LINUX_S_IFREG 0100000
+#define LINUX_S_IFBLK 0060000
+#define LINUX_S_IFDIR 0040000
+#define LINUX_S_IFCHR 0020000
+#define LINUX_S_IFIFO 0010000
+#define LINUX_S_ISUID 0004000
+#define LINUX_S_ISGID 0002000
+#define LINUX_S_ISVTX 0001000
+
+#define LINUX_S_IRWXU 00700
+#define LINUX_S_IRUSR 00400
+#define LINUX_S_IWUSR 00200
+#define LINUX_S_IXUSR 00100
+
+#define LINUX_S_IRWXG 00070
+#define LINUX_S_IRGRP 00040
+#define LINUX_S_IWGRP 00020
+#define LINUX_S_IXGRP 00010
+
+#define LINUX_S_IRWXO 00007
+#define LINUX_S_IROTH 00004
+#define LINUX_S_IWOTH 00002
+#define LINUX_S_IXOTH 00001
+
+#define LINUX_S_ISLNK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
+#define LINUX_S_ISREG(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFREG)
+#define LINUX_S_ISDIR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFDIR)
+#define LINUX_S_ISCHR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFCHR)
+#define LINUX_S_ISBLK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFBLK)
+#define LINUX_S_ISFIFO(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFIFO)
+#define LINUX_S_ISSOCK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFSOCK)
+
+/*
+ * ext2_icount_t abstraction
+ */
+#define EXT2_ICOUNT_OPT_INCREMENT 0x01
+
+typedef struct ext2_icount *ext2_icount_t;
+
+/*
+ * Flags for ext2fs_bmap
+ */
+#define BMAP_ALLOC 1
+
+/*
+ * For checking structure magic numbers...
+ */
+
+#define EXT2_CHECK_MAGIC(struct, code) \
+ if ((struct)->magic != (code)) return (code)
+
+
+/*
+ * The ext2fs library private definition of the ext2 superblock, so we
+ * don't have to depend on the kernel's definition of the superblock,
+ * which might not have the latest features.
+ */
+struct ext2fs_sb {
+ __u32 s_inodes_count; /* Inodes count */
+ __u32 s_blocks_count; /* Blocks count */
+ __u32 s_r_blocks_count; /* Reserved blocks count */
+ __u32 s_free_blocks_count; /* Free blocks count */
+ __u32 s_free_inodes_count; /* Free inodes count */
+ __u32 s_first_data_block; /* First Data Block */
+ __u32 s_log_block_size; /* Block size */
+ __s32 s_log_frag_size; /* Fragment size */
+ __u32 s_blocks_per_group; /* # Blocks per group */
+ __u32 s_frags_per_group; /* # Fragments per group */
+ __u32 s_inodes_per_group; /* # Inodes per group */
+ __u32 s_mtime; /* Mount time */
+ __u32 s_wtime; /* Write time */
+ __u16 s_mnt_count; /* Mount count */
+ __s16 s_max_mnt_count; /* Maximal mount count */
+ __u16 s_magic; /* Magic signature */
+ __u16 s_state; /* File system state */
+ __u16 s_errors; /* Behaviour when detecting errors */
+ __u16 s_minor_rev_level; /* minor revision level */
+ __u32 s_lastcheck; /* time of last check */
+ __u32 s_checkinterval; /* max. time between checks */
+ __u32 s_creator_os; /* OS */
+ __u32 s_rev_level; /* Revision level */
+ __u16 s_def_resuid; /* Default uid for reserved blocks */
+ __u16 s_def_resgid; /* Default gid for reserved blocks */
+ /*
+ * These fields are for EXT2_DYNAMIC_REV superblocks only.
+ *
+ * Note: the difference between the compatible feature set and
+ * the incompatible feature set is that if there is a bit set
+ * in the incompatible feature set that the kernel doesn't
+ * know about, it should refuse to mount the filesystem.
+ *
+ * e2fsck's requirements are more strict; if it doesn't know
+ * about a feature in either the compatible or incompatible
+ * feature set, it must abort and not try to meddle with
+ * things it doesn't understand...
+ */
+ __u32 s_first_ino; /* First non-reserved inode */
+ __u16 s_inode_size; /* size of inode structure */
+ __u16 s_block_group_nr; /* block group # of this superblock */
+ __u32 s_feature_compat; /* compatible feature set */
+ __u32 s_feature_incompat; /* incompatible feature set */
+ __u32 s_feature_ro_compat; /* readonly-compatible feature set */
+ __u8 s_uuid[16]; /* 128-bit uuid for volume */
+ char s_volume_name[16]; /* volume name */
+ char s_last_mounted[64]; /* directory where last mounted */
+ __u32 s_algorithm_usage_bitmap; /* For compression */
+ /*
+ * Performance hints. Directory preallocation should only
+ * happen if the EXT2_COMPAT_PREALLOC flag is on.
+ */
+ __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
+ __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
+ __u16 s_padding1;
+ /*
+ * Journaling support.
+ */
+ __u8 s_journal_uuid[16]; /* uuid of journal superblock */
+ __u32 s_journal_inum; /* inode number of journal file */
+
+ __u32 s_reserved[199]; /* Padding to the end of the block */
+};
+
+/*
+ * Feature set definitions (that might not be in ext2_fs.h
+ */
+
+#ifndef EXT2_FEATURE_COMPAT_DIR_PREALLOC
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001
+#endif
+
+#ifndef EXT2_FEATURE_COMPAT_IMAGIC_INODES /* for AFS, etc. */
+#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002
+#define EXT2_IMAGIC_FL 0x00002000
+#endif
+
+#ifndef EXT3_FEATURE_COMPAT_HAS_JOURNAL
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
+#endif
+
+#ifndef EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
+#endif
+
+#ifndef EXT2_FEATURE_RO_COMPAT_LARGE_FILE
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
+#define i_size_high i_dir_acl
+#endif
+
+#ifndef EXT2_FEATURE_RO_COMPAT_BTREE_DIR
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
+#endif
+
+#ifndef EXT2_FEATURE_INCOMPAT_COMPRESSION
+#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001
+#endif
+
+#ifndef EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
+#endif
+
+#ifndef EXT3_FEATURE_INCOMPAT_RECOVER
+#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */
+#endif
+
+#define EXT2_LIB_FEATURE_COMPAT_SUPP (EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
+ EXT2_FEATURE_COMPAT_IMAGIC_INODES|\
+ EXT3_FEATURE_COMPAT_HAS_JOURNAL)
+#define EXT2_LIB_FEATURE_INCOMPAT_SUPP EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
+/*
+ * function prototypes
+ */
+
+/* alloc.c */
+extern errcode_t ext2fs_new_inode(ext2_filsys fs, ino_t dir, int mode,
+ ext2fs_inode_bitmap map, ino_t *ret);
+extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
+ ext2fs_block_bitmap map, blk_t *ret);
+extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
+ blk_t finish, int num,
+ ext2fs_block_bitmap map,
+ blk_t *ret);
+extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
+ char *block_buf, blk_t *ret);
+
+/* alloc_tables.c */
+extern errcode_t ext2fs_allocate_tables(ext2_filsys fs);
+extern errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
+ ext2fs_block_bitmap bmap);
+
+/* badblocks.c */
+extern errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret,
+ int size);
+extern errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb,
+ blk_t blk);
+extern int ext2fs_badblocks_list_test(ext2_badblocks_list bb,
+ blk_t blk);
+extern errcode_t
+ ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
+ ext2_badblocks_iterate *ret);
+extern int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter,
+ blk_t *blk);
+extern void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter);
+extern errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
+ ext2_badblocks_list *dest);
+
+/* bb_compat */
+extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
+extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
+extern int badblocks_list_test(badblocks_list bb, blk_t blk);
+extern errcode_t badblocks_list_iterate_begin(badblocks_list bb,
+ badblocks_iterate *ret);
+extern int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk);
+extern void badblocks_list_iterate_end(badblocks_iterate iter);
+extern void badblocks_list_free(badblocks_list bb);
+
+/* bb_inode.c */
+extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
+ ext2_badblocks_list bb_list);
+
+/* bitmaps.c */
+extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
+extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
+extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+ __u32 end,
+ __u32 real_end,
+ const char *descr,
+ ext2fs_generic_bitmap *ret);
+extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
+ const char *descr,
+ ext2fs_block_bitmap *ret);
+extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
+ const char *descr,
+ ext2fs_inode_bitmap *ret);
+extern errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
+ ino_t end, ino_t *oend);
+extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
+ blk_t end, blk_t *oend);
+extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
+extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
+extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
+extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
+
+/* block.c */
+extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
+ ino_t ino,
+ int flags,
+ char *block_buf,
+ int (*func)(ext2_filsys fs,
+ blk_t *blocknr,
+ int blockcnt,
+ void *priv_data),
+ void *priv_data);
+errcode_t ext2fs_block_iterate2(ext2_filsys fs,
+ ino_t ino,
+ int flags,
+ char *block_buf,
+ int (*func)(ext2_filsys fs,
+ blk_t *blocknr,
+ e2_blkcnt_t blockcnt,
+ blk_t ref_blk,
+ int ref_offset,
+ void *priv_data),
+ void *priv_data);
+
+/* bmap.c */
+extern errcode_t ext2fs_bmap(ext2_filsys fs, ino_t ino,
+ struct ext2_inode *inode,
+ char *block_buf, int bmap_flags,
+ blk_t block, blk_t *phys_blk);
+
+
+#if 0
+/* bmove.c */
+extern errcode_t ext2fs_move_blocks(ext2_filsys fs,
+ ext2fs_block_bitmap reserve,
+ ext2fs_block_bitmap alloc_map,
+ int flags);
+#endif
+
+/* check_desc.c */
+extern errcode_t ext2fs_check_desc(ext2_filsys fs);
+
+/* closefs.c */
+extern errcode_t ext2fs_close(ext2_filsys fs);
+extern errcode_t ext2fs_flush(ext2_filsys fs);
+extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block);
+
+/* cmp_bitmaps.c */
+extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
+ ext2fs_block_bitmap bm2);
+extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
+ ext2fs_inode_bitmap bm2);
+
+/* dblist.c */
+
+extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ino_t *ret_num_dirs);
+extern errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
+extern errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ino_t ino,
+ blk_t blk, int blockcnt);
+extern errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
+ int (*func)(ext2_filsys fs, struct ext2_db_entry *db_info,
+ void *priv_data),
+ void *priv_data);
+extern errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ino_t ino,
+ blk_t blk, int blockcnt);
+extern errcode_t ext2fs_copy_dblist(ext2_dblist src,
+ ext2_dblist *dest);
+extern int ext2fs_dblist_count(ext2_dblist dblist);
+
+/* dblist_dir.c */
+extern errcode_t
+ ext2fs_dblist_dir_iterate(ext2_dblist dblist,
+ int flags,
+ char *block_buf,
+ int (*func)(ino_t dir,
+ int entry,
+ struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data),
+ void *priv_data);
+
+/* dirblock.c */
+extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
+ void *buf);
+extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
+ void *buf);
+
+/* dir_iterate.c */
+extern errcode_t ext2fs_dir_iterate(ext2_filsys fs,
+ ino_t dir,
+ int flags,
+ char *block_buf,
+ int (*func)(struct ext2_dir_entry *dirent,
+ int offset,
+ int blocksize,
+ char *buf,
+ void *priv_data),
+ void *priv_data);
+
+/* dupfs.c */
+extern errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest);
+
+/* expanddir.c */
+extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ino_t dir);
+
+/* fileio.c */
+extern errcode_t ext2fs_file_open(ext2_filsys fs, ino_t ino,
+ int flags, ext2_file_t *ret);
+extern ext2_filsys ext2fs_file_get_fs(ext2_file_t file);
+extern errcode_t ext2fs_file_close(ext2_file_t file);
+extern errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
+ unsigned int wanted, unsigned int *got);
+extern errcode_t ext2fs_file_write(ext2_file_t file, void *buf,
+ unsigned int nbytes, unsigned int *written);
+extern errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
+ int whence, ext2_off_t *ret_pos);
+extern ext2_off_t ext2fs_file_get_size(ext2_file_t file);
+extern errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size);
+
+/* freefs.c */
+extern void ext2fs_free(ext2_filsys fs);
+extern void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap);
+extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
+extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
+extern void ext2fs_free_dblist(ext2_dblist dblist);
+extern void ext2fs_badblocks_list_free(badblocks_list bb);
+
+/* getsize.c */
+extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
+ blk_t *retblocks);
+
+/* initialize.c */
+extern errcode_t ext2fs_initialize(const char *name, int flags,
+ struct ext2_super_block *param,
+ io_manager manager, ext2_filsys *ret_fs);
+
+/* inode.c */
+extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
+ ext2_inode_scan *ret_scan);
+extern void ext2fs_close_inode_scan(ext2_inode_scan scan);
+extern errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
+ struct ext2_inode *inode);
+extern errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
+ int group);
+extern void ext2fs_set_inode_callback
+ (ext2_inode_scan scan,
+ errcode_t (*done_group)(ext2_filsys fs,
+ ext2_inode_scan scan,
+ dgrp_t group,
+ void * priv_data),
+ void *done_group_data);
+extern int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
+ int clear_flags);
+extern errcode_t ext2fs_read_inode (ext2_filsys fs, ino_t ino,
+ struct ext2_inode * inode);
+extern errcode_t ext2fs_write_inode(ext2_filsys fs, ino_t ino,
+ struct ext2_inode * inode);
+extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks);
+extern errcode_t ext2fs_check_directory(ext2_filsys fs, ino_t ino);
+
+/* icount.c */
+extern void ext2fs_free_icount(ext2_icount_t icount);
+extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, int size,
+ ext2_icount_t hint, ext2_icount_t *ret);
+extern errcode_t ext2fs_create_icount(ext2_filsys fs, int flags, int size,
+ ext2_icount_t *ret);
+extern errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ino_t ino,
+ __u16 *ret);
+extern errcode_t ext2fs_icount_increment(ext2_icount_t icount, ino_t ino,
+ __u16 *ret);
+extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ino_t ino,
+ __u16 *ret);
+extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ino_t ino,
+ __u16 count);
+extern ino_t ext2fs_get_icount_size(ext2_icount_t icount);
+#if 0
+errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
+#endif
+
+/* ismounted.c */
+extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
+
+/* namei.c */
+extern errcode_t ext2fs_lookup(ext2_filsys fs, ino_t dir, const char *name,
+ int namelen, char *buf, ino_t *inode);
+extern errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd,
+ const char *name, ino_t *inode);
+errcode_t ext2fs_namei_follow(ext2_filsys fs, ino_t root, ino_t cwd,
+ const char *name, ino_t *inode);
+extern errcode_t ext2fs_follow_link(ext2_filsys fs, ino_t root, ino_t cwd,
+ ino_t inode, ino_t *res_inode);
+
+/* native.c */
+int ext2fs_native_flag(void);
+
+/* newdir.c */
+extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ino_t dir_ino,
+ ino_t parent_ino, char **block);
+
+/* mkdir.c */
+extern errcode_t ext2fs_mkdir(ext2_filsys fs, ino_t parent, ino_t inum,
+ const char *name);
+
+/* openfs.c */
+extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
+ int block_size, io_manager manager,
+ ext2_filsys *ret_fs);
+
+/* get_pathname.c */
+extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ino_t dir, ino_t ino,
+ char **name);
+
+/* link.c */
+errcode_t ext2fs_link(ext2_filsys fs, ino_t dir, const char *name,
+ ino_t ino, int flags);
+errcode_t ext2fs_unlink(ext2_filsys fs, ino_t dir, const char *name,
+ ino_t ino, int flags);
+
+/* read_bb.c */
+extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
+ ext2_badblocks_list *bb_list);
+
+/* read_bb_file.c */
+#if 0
+extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
+ ext2_badblocks_list *bb_list,
+ void (*invalid)(ext2_filsys fs,
+ blk_t blk));
+#endif
+
+/* rs_bitmap.c */
+extern errcode_t ext2fs_resize_generic_bitmap(__u32 new_end,
+ __u32 new_real_end,
+ ext2fs_generic_bitmap bmap);
+extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
+ ext2fs_inode_bitmap bmap);
+extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
+ ext2fs_block_bitmap bmap);
+extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
+ ext2fs_generic_bitmap *dest);
+
+/* swapfs.c */
+extern void ext2fs_swap_super(struct ext2_super_block * super);
+extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
+extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
+ struct ext2_inode *f, int hostorder);
+
+/* valid_blk.c */
+extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
+
+/* version.c */
+extern int ext2fs_parse_version_string(const char *ver_string);
+extern int ext2fs_get_library_version(const char **ver_string,
+ const char **date_string);
+
+/* inline functions */
+extern errcode_t ext2fs_get_mem(unsigned long size, void **ptr);
+extern errcode_t ext2fs_free_mem(void **ptr);
+extern errcode_t ext2fs_resize_mem(unsigned long old_size,
+ unsigned long size, void **ptr);
+extern void ext2fs_mark_super_dirty(ext2_filsys fs);
+extern void ext2fs_mark_changed(ext2_filsys fs);
+extern int ext2fs_test_changed(ext2_filsys fs);
+extern void ext2fs_mark_valid(ext2_filsys fs);
+extern void ext2fs_unmark_valid(ext2_filsys fs);
+extern int ext2fs_test_valid(ext2_filsys fs);
+extern void ext2fs_mark_ib_dirty(ext2_filsys fs);
+extern void ext2fs_mark_bb_dirty(ext2_filsys fs);
+extern int ext2fs_test_ib_dirty(ext2_filsys fs);
+extern int ext2fs_test_bb_dirty(ext2_filsys fs);
+extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
+extern int ext2fs_group_of_ino(ext2_filsys fs, ino_t ino);
+
+/*
+ * The actual inlined functions definitions themselves...
+ *
+ * If NO_INLINE_FUNCS is defined, then we won't try to do inline
+ * functions at all!
+ */
+#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
+#ifdef INCLUDE_INLINE_FUNCS
+#define _INLINE_ extern
+#else
+#ifdef __GNUC__
+#define _INLINE_ extern __inline__
+#else /* For Watcom C */
+#define _INLINE_ extern inline
+#endif
+#endif
+
+#ifndef EXT2_CUSTOM_MEMORY_ROUTINES
+/*
+ * Allocate memory
+ */
+_INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void **ptr)
+{
+ *ptr = malloc(size);
+ if (!*ptr)
+ return EXT2_ET_NO_MEMORY;
+ return 0;
+}
+
+/*
+ * Free memory
+ */
+_INLINE_ errcode_t ext2fs_free_mem(void **ptr)
+{
+ free(*ptr);
+ *ptr = 0;
+ return 0;
+}
+
+/*
+ * Resize memory
+ */
+_INLINE_ errcode_t ext2fs_resize_mem(unsigned long old_size,
+ unsigned long size, void **ptr)
+{
+ void *p;
+
+ p = realloc(*ptr, size);
+ if (!p)
+ return EXT2_ET_NO_MEMORY;
+ *ptr = p;
+ return 0;
+}
+#endif /* Custom memory routines */
+
+/*
+ * Mark a filesystem superblock as dirty
+ */
+_INLINE_ void ext2fs_mark_super_dirty(ext2_filsys fs)
+{
+ fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Mark a filesystem as changed
+ */
+_INLINE_ void ext2fs_mark_changed(ext2_filsys fs)
+{
+ fs->flags |= EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Check to see if a filesystem has changed
+ */
+_INLINE_ int ext2fs_test_changed(ext2_filsys fs)
+{
+ return (fs->flags & EXT2_FLAG_CHANGED);
+}
+
+/*
+ * Mark a filesystem as valid
+ */
+_INLINE_ void ext2fs_mark_valid(ext2_filsys fs)
+{
+ fs->flags |= EXT2_FLAG_VALID;
+}
+
+/*
+ * Mark a filesystem as NOT valid
+ */
+_INLINE_ void ext2fs_unmark_valid(ext2_filsys fs)
+{
+ fs->flags &= ~EXT2_FLAG_VALID;
+}
+
+/*
+ * Check to see if a filesystem is valid
+ */
+_INLINE_ int ext2fs_test_valid(ext2_filsys fs)
+{
+ return (fs->flags & EXT2_FLAG_VALID);
+}
+
+/*
+ * Mark the inode bitmap as dirty
+ */
+_INLINE_ void ext2fs_mark_ib_dirty(ext2_filsys fs)
+{
+ fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Mark the block bitmap as dirty
+ */
+_INLINE_ void ext2fs_mark_bb_dirty(ext2_filsys fs)
+{
+ fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
+}
+
+/*
+ * Check to see if a filesystem's inode bitmap is dirty
+ */
+_INLINE_ int ext2fs_test_ib_dirty(ext2_filsys fs)
+{
+ return (fs->flags & EXT2_FLAG_IB_DIRTY);
+}
+
+/*
+ * Check to see if a filesystem's block bitmap is dirty
+ */
+_INLINE_ int ext2fs_test_bb_dirty(ext2_filsys fs)
+{
+ return (fs->flags & EXT2_FLAG_BB_DIRTY);
+}
+
+/*
+ * Return the group # of a block
+ */
+_INLINE_ int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
+{
+ return (blk - fs->super->s_first_data_block) /
+ fs->super->s_blocks_per_group;
+}
+
+/*
+ * Return the group # of an inode number
+ */
+_INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ino_t ino)
+{
+ return (ino - 1) / fs->super->s_inodes_per_group;
+}
+#undef _INLINE_
+#endif
+
+#endif /* _EXT2FS_EXT2FS_H */
--- /dev/null
+/*
+ * Structure of a fdisk driver descriptor (block 0)
+ * and partition table (blocks 1..n).
+ *
+ * Copyright 2000 IBM / Peter Bergner / David Engebretsen
+ */
+
+#define ACTIVE_FLAG 0x80
+
+#define EXTENDED 0x05
+#define WIN98_EXTENDED 0x0f
+#define LINUX_PARTITION 0x81
+#define LINUX_SWAP 0x82
+#define LINUX_NATIVE 0x83
+#define LINUX_EXTENDED 0x85
+
+struct fdisk_partition {
+ unsigned char boot_ind; /* 0x80 - active */
+ unsigned char head; /* starting head */
+ unsigned char sector; /* starting sector */
+ unsigned char cyl; /* starting cylinder */
+ unsigned char sys_ind; /* What partition type */
+ unsigned char end_head; /* end head */
+ unsigned char end_sector; /* end sector */
+ unsigned char end_cyl; /* end cylinder */
+ unsigned char start4[4]; /* starting sector counting from 0 */
+ unsigned char size4[4]; /* nr of sectors in partition */
+};
--- /dev/null
+/*
+ Definitions for talking to the Open Firmware PROM on
+ Power Macintosh computers.
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef FILE_H
+#define FILE_H
+
+#include "types.h"
+#include "stddef.h"
+#include "prom.h"
+
+struct boot_file_t;
+#include "fs.h"
+
+#define FILE_MAX_PATH 1024
+
+/* Simple error codes */
+#define FILE_ERR_OK 0
+#define FILE_ERR_EOF -1
+#define FILE_ERR_NOTFOUND -2
+#define FILE_CANT_SEEK -3
+#define FILE_IOERR -4
+#define FILE_BAD_PATH -5
+#define FILE_ERR_BAD_TYPE -6
+#define FILE_ERR_BAD_FSYS -7
+#define FILE_ERR_SYMLINK_LOOP -8
+#define FILE_ERR_LENGTH -9
+
+/* Device kind */
+#define FILE_DEVICE_BLOCK 1
+#define FILE_DEVICE_NET 2
+
+struct boot_fspec_t {
+ char* dev; /* OF device path */
+ int part; /* Partition number or -1 */
+ char* file; /* File path */
+};
+
+struct boot_file_t {
+
+ /* File access methods */
+ const struct fs_t *fs;
+
+ /* Filesystem private (to be broken once we have a
+ * better malloc'ator)
+ */
+
+ int device_kind;
+ ihandle of_device;
+ ino_t inode;
+ __u64 pos;
+ unsigned char* buffer;
+ __u64 len;
+// unsigned int dev_blk_size;
+// unsigned int part_start;
+// unsigned int part_count;
+};
+
+extern int open_file( const struct boot_fspec_t* spec,
+ struct boot_file_t* file);
+
+extern int validate_fspec(
+ struct boot_fspec_t* spec,
+ char* default_device,
+ int default_part);
+extern char *parse_device_path(
+ char* of_device,
+ char** file_spec,
+ int* partition);
+
+
+
+#endif
--- /dev/null
+/*
+ FileSystems common definitions
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef FS_H
+#define FS_H
+
+#include "partition.h"
+#include "file.h"
+
+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);
+
+ int (*read)( struct boot_file_t* file,
+ unsigned int size,
+ void* buffer);
+
+ int (*seek)( struct boot_file_t* file,
+ unsigned int newpos);
+
+ int (*close)( struct boot_file_t* file);
+};
+
+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 );
+
+#if DEBUG
+# define DEBUG_ENTER prom_printf( "--> %s\n", __PRETTY_FUNCTION__ );
+# define DEBUG_LEAVE(str) \
+ prom_printf( "<-- %s - %s\n", __PRETTY_FUNCTION__, #str );
+# define DEBUG_F(fmt, args...)\
+{\
+ prom_printf( " %s - ", __PRETTY_FUNCTION__ );\
+ prom_printf( fmt, ## args );\
+}
+# define DEBUG_OPEN DEBUG_F( "dev=%s, part=0x%08lx (%d), file_name=%s\n",\
+ dev_name, part, part ? part->part_number : -1,\
+ file_name);
+#else
+#define DEBUG_ENTER
+#define DEBUG_LEAVE(x)
+#define DEBUG_F(fmt, args...)
+#define DEBUG_OPEN
+#endif
+
+#endif
--- /dev/null
+extern void fxDisplaySplash(struct boot_fspec_t *filespec);
+int fxReadImage(struct boot_file_t *file, unsigned int filesize, void *base);
+
--- /dev/null
+#ifndef _LINUX_ELF_H
+#define _LINUX_ELF_H
+
+#include <types.h>
+#include <asm/elf.h>
+
+/* 32-bit ELF base types. */
+typedef __u32 Elf32_Addr;
+typedef __u16 Elf32_Half;
+typedef __u32 Elf32_Off;
+typedef __s32 Elf32_Sword;
+typedef __u32 Elf32_Word;
+
+/* 64-bit ELF base types. */
+typedef __u64 Elf64_Addr;
+typedef __u16 Elf64_Half;
+typedef __s16 Elf64_SHalf;
+typedef __u64 Elf64_Off;
+typedef __s64 Elf64_Sword;
+typedef __u64 Elf64_Word;
+
+/* These constants are for the segment types stored in the image headers */
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7fffffff
+#define PT_MIPS_REGINFO 0x70000000
+
+/* Flags in the e_flags field of the header */
+#define EF_MIPS_NOREORDER 0x00000001
+#define EF_MIPS_PIC 0x00000002
+#define EF_MIPS_CPIC 0x00000004
+#define EF_MIPS_ARCH 0xf0000000
+
+/* These constants define the different elf file types */
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_LOPROC 0xff00
+#define ET_HIPROC 0xffff
+
+/* These constants define the various ELF target machines */
+#define EM_NONE 0
+#define EM_M32 1
+#define EM_SPARC 2
+#define EM_386 3
+#define EM_68K 4
+#define EM_88K 5
+#define EM_486 6 /* Perhaps disused */
+#define EM_860 7
+
+#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
+
+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */
+
+#define EM_PARISC 15 /* HPPA */
+
+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
+
+#define EM_PPC 20 /* PowerPC */
+#define EM_PPC64 21 /* PowerPC 64-bit */
+
+#define EM_SPARCV9 43 /* SPARC v9 64-bit */
+
+/*
+ * This is an interim value that we will use until the committee comes
+ * up with a final number.
+ */
+#define EM_ALPHA 0x9026
+
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+#define DT_MIPS_RLD_VERSION 0x70000001
+#define DT_MIPS_TIME_STAMP 0x70000002
+#define DT_MIPS_ICHECKSUM 0x70000003
+#define DT_MIPS_IVERSION 0x70000004
+#define DT_MIPS_FLAGS 0x70000005
+ #define RHF_NONE 0
+ #define RHF_HARDWAY 1
+ #define RHF_NOTPOT 2
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+#define DT_MIPS_CONFLICT 0x70000008
+#define DT_MIPS_LIBLIST 0x70000009
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a
+#define DT_MIPS_CONFLICTNO 0x7000000b
+#define DT_MIPS_LIBLISTNO 0x70000010
+#define DT_MIPS_SYMTABNO 0x70000011
+#define DT_MIPS_UNREFEXTNO 0x70000012
+#define DT_MIPS_GOTSYM 0x70000013
+#define DT_MIPS_HIPAGENO 0x70000014
+#define DT_MIPS_RLD_MAP 0x70000016
+
+/* This info is needed when parsing the symbol table */
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+
+#define ELF32_ST_BIND(x) ((x) >> 4)
+#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
+
+/* Symbolic values for the entries in the auxiliary table
+ put on the initial stack */
+#define AT_NULL 0 /* end of vector */
+#define AT_IGNORE 1 /* entry should be ignored */
+#define AT_EXECFD 2 /* file descriptor of program */
+#define AT_PHDR 3 /* program headers for program */
+#define AT_PHENT 4 /* size of program header entry */
+#define AT_PHNUM 5 /* number of program headers */
+#define AT_PAGESZ 6 /* system page size */
+#define AT_BASE 7 /* base address of interpreter */
+#define AT_FLAGS 8 /* flags */
+#define AT_ENTRY 9 /* entry point of program */
+#define AT_NOTELF 10 /* program is not ELF */
+#define AT_UID 11 /* real uid */
+#define AT_EUID 12 /* effective uid */
+#define AT_GID 13 /* real gid */
+#define AT_EGID 14 /* effective gid */
+#define AT_PLATFORM 15 /* string identifying CPU for optimizations */
+#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
+
+typedef struct dynamic{
+ Elf32_Sword d_tag;
+ union{
+ Elf32_Sword d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+ Elf64_Word d_tag; /* entry tag value */
+ union {
+ Elf64_Word d_val;
+ Elf64_Word d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+/* The following are used with relocations */
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+#define R_386_NONE 0
+#define R_386_32 1
+#define R_386_PC32 2
+#define R_386_GOT32 3
+#define R_386_PLT32 4
+#define R_386_COPY 5
+#define R_386_GLOB_DAT 6
+#define R_386_JMP_SLOT 7
+#define R_386_RELATIVE 8
+#define R_386_GOTOFF 9
+#define R_386_GOTPC 10
+#define R_386_NUM 11
+
+#define R_MIPS_NONE 0
+#define R_MIPS_16 1
+#define R_MIPS_32 2
+#define R_MIPS_REL32 3
+#define R_MIPS_26 4
+#define R_MIPS_HI16 5
+#define R_MIPS_LO16 6
+#define R_MIPS_GPREL16 7
+#define R_MIPS_LITERAL 8
+#define R_MIPS_GOT16 9
+#define R_MIPS_PC16 10
+#define R_MIPS_CALL16 11
+#define R_MIPS_GPREL32 12
+/* The remaining relocs are defined on Irix, although they are not
+ in the MIPS ELF ABI. */
+#define R_MIPS_UNUSED1 13
+#define R_MIPS_UNUSED2 14
+#define R_MIPS_UNUSED3 15
+#define R_MIPS_SHIFT5 16
+#define R_MIPS_SHIFT6 17
+#define R_MIPS_64 18
+#define R_MIPS_GOT_DISP 19
+#define R_MIPS_GOT_PAGE 20
+#define R_MIPS_GOT_OFST 21
+/*
+ * The following two relocation types are specified in the the MIPS ABI
+ * conformance guide version 1.2 but not yet in the psABI.
+ */
+#define R_MIPS_GOTHI16 22
+#define R_MIPS_GOTLO16 23
+#define R_MIPS_SUB 24
+#define R_MIPS_INSERT_A 25
+#define R_MIPS_INSERT_B 26
+#define R_MIPS_DELETE 27
+#define R_MIPS_HIGHER 28
+#define R_MIPS_HIGHEST 29
+/*
+ * The following two relocation types are specified in the the MIPS ABI
+ * conformance guide version 1.2 but not yet in the psABI.
+ */
+#define R_MIPS_CALLHI16 30
+#define R_MIPS_CALLLO16 31
+/*
+ * This range is reserved for vendor specific relocations.
+ */
+#define R_MIPS_LOVENDOR 100
+#define R_MIPS_HIVENDOR 127
+
+
+/*
+ * Sparc ELF relocation types
+ */
+#define R_SPARC_NONE 0
+#define R_SPARC_8 1
+#define R_SPARC_16 2
+#define R_SPARC_32 3
+#define R_SPARC_DISP8 4
+#define R_SPARC_DISP16 5
+#define R_SPARC_DISP32 6
+#define R_SPARC_WDISP30 7
+#define R_SPARC_WDISP22 8
+#define R_SPARC_HI22 9
+#define R_SPARC_22 10
+#define R_SPARC_13 11
+#define R_SPARC_LO10 12
+#define R_SPARC_GOT10 13
+#define R_SPARC_GOT13 14
+#define R_SPARC_GOT22 15
+#define R_SPARC_PC10 16
+#define R_SPARC_PC22 17
+#define R_SPARC_WPLT30 18
+#define R_SPARC_COPY 19
+#define R_SPARC_GLOB_DAT 20
+#define R_SPARC_JMP_SLOT 21
+#define R_SPARC_RELATIVE 22
+#define R_SPARC_UA32 23
+#define R_SPARC_PLT32 24
+#define R_SPARC_HIPLT22 25
+#define R_SPARC_LOPLT10 26
+#define R_SPARC_PCPLT32 27
+#define R_SPARC_PCPLT22 28
+#define R_SPARC_PCPLT10 29
+#define R_SPARC_10 30
+#define R_SPARC_11 31
+#define R_SPARC_WDISP16 40
+#define R_SPARC_WDISP19 41
+#define R_SPARC_7 43
+#define R_SPARC_5 44
+#define R_SPARC_6 45
+
+/* Bits present in AT_HWCAP, primarily for Sparc32. */
+
+#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */
+#define HWCAP_SPARC_STBAR 2
+#define HWCAP_SPARC_SWAP 4
+#define HWCAP_SPARC_MULDIV 8
+#define HWCAP_SPARC_V9 16
+
+
+/*
+ * 68k ELF relocation types
+ */
+#define R_68K_NONE 0
+#define R_68K_32 1
+#define R_68K_16 2
+#define R_68K_8 3
+#define R_68K_PC32 4
+#define R_68K_PC16 5
+#define R_68K_PC8 6
+#define R_68K_GOT32 7
+#define R_68K_GOT16 8
+#define R_68K_GOT8 9
+#define R_68K_GOT32O 10
+#define R_68K_GOT16O 11
+#define R_68K_GOT8O 12
+#define R_68K_PLT32 13
+#define R_68K_PLT16 14
+#define R_68K_PLT8 15
+#define R_68K_PLT32O 16
+#define R_68K_PLT16O 17
+#define R_68K_PLT8O 18
+#define R_68K_COPY 19
+#define R_68K_GLOB_DAT 20
+#define R_68K_JMP_SLOT 21
+#define R_68K_RELATIVE 22
+
+/*
+ * Alpha ELF relocation types
+ */
+#define R_ALPHA_NONE 0 /* No reloc */
+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
+#define R_ALPHA_OP_PUSH 12 /* OP stack push */
+#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */
+#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */
+#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */
+#define R_ALPHA_GPVALUE 16
+#define R_ALPHA_GPRELHIGH 17
+#define R_ALPHA_GPRELLOW 18
+#define R_ALPHA_IMMED_GP_16 19
+#define R_ALPHA_IMMED_GP_HI32 20
+#define R_ALPHA_IMMED_SCN_HI32 21
+#define R_ALPHA_IMMED_BR_HI32 22
+#define R_ALPHA_IMMED_LO32 23
+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
+
+/* Legal values for e_flags field of Elf64_Ehdr. */
+
+#define EF_ALPHA_32BIT 1 /* All addresses are below 2GB */
+
+
+typedef struct elf32_rel {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct elf64_rel {
+ Elf64_Addr r_offset; /* Location at which to apply the action */
+ Elf64_Word r_info; /* index and type of relocation */
+} Elf64_Rel;
+
+typedef struct elf32_rela{
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+typedef struct elf64_rela {
+ Elf64_Addr r_offset; /* Location at which to apply the action */
+ Elf64_Word r_info; /* index and type of relocation */
+ Elf64_Word r_addend; /* Constant addend used to compute value */
+} Elf64_Rela;
+
+typedef struct elf32_sym{
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Half st_shndx;
+} Elf32_Sym;
+
+typedef struct elf64_sym {
+ Elf32_Word st_name; /* Symbol name, index in string tbl (yes, Elf32) */
+ unsigned char st_info; /* Type and binding attributes */
+ unsigned char st_other; /* No defined meaning, 0 */
+ Elf64_Half st_shndx; /* Associated section index */
+ Elf64_Addr st_value; /* Value of the symbol */
+ Elf64_Word st_size; /* Associated symbol size */
+} Elf64_Sym;
+
+
+#define EI_NIDENT 16
+
+/* Minimum amount of the header we need to determine whether
+ * we have an executable PPC32/PPC64 Elf file or not.
+ */
+typedef struct elf_ident_t {
+ unsigned char e_ident[EI_NIDENT];
+ __u16 e_type;
+ __u16 e_machine;
+} Elf_Ident;
+
+typedef struct elf32_hdr{
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry; /* Entry point */
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct elf64_hdr {
+ unsigned char e_ident[16]; /* ELF "magic number" */
+ Elf64_SHalf e_type;
+ Elf64_Half e_machine;
+ __s32 e_version;
+ Elf64_Addr e_entry; /* Entry point virtual address */
+ Elf64_Off e_phoff; /* Program header table file offset */
+ Elf64_Off e_shoff; /* Section header table file offset */
+ __s32 e_flags;
+ Elf64_SHalf e_ehsize;
+ Elf64_SHalf e_phentsize;
+ Elf64_SHalf e_phnum;
+ Elf64_SHalf e_shentsize;
+ Elf64_SHalf e_shnum;
+ Elf64_SHalf e_shstrndx;
+} Elf64_Ehdr;
+
+/* These constants define the permissions on sections in the program
+ header, p_flags. */
+#define PF_R 0x4
+#define PF_W 0x2
+#define PF_X 0x1
+
+typedef struct elf32_phdr{
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+typedef struct elf64_phdr {
+ __s32 p_type;
+ __s32 p_flags;
+ Elf64_Off p_offset; /* Segment file offset */
+ Elf64_Addr p_vaddr; /* Segment virtual address */
+ Elf64_Addr p_paddr; /* Segment physical address */
+ Elf64_Word p_filesz; /* Segment size in file */
+ Elf64_Word p_memsz; /* Segment size in memory */
+ Elf64_Word p_align; /* Segment alignment, file & memory */
+} Elf64_Phdr;
+
+/* sh_type */
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+#define SHT_NUM 12
+#define SHT_LOPROC 0x70000000
+#define SHT_HIPROC 0x7fffffff
+#define SHT_LOUSER 0x80000000
+#define SHT_HIUSER 0xffffffff
+#define SHT_MIPS_LIST 0x70000000
+#define SHT_MIPS_CONFLICT 0x70000002
+#define SHT_MIPS_GPTAB 0x70000003
+#define SHT_MIPS_UCODE 0x70000004
+
+/* sh_flags */
+#define SHF_WRITE 0x1
+#define SHF_ALLOC 0x2
+#define SHF_EXECINSTR 0x4
+#define SHF_MASKPROC 0xf0000000
+#define SHF_MIPS_GPREL 0x10000000
+
+/* special section indexes */
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00
+#define SHN_LOPROC 0xff00
+#define SHN_HIPROC 0xff1f
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+#define SHN_HIRESERVE 0xffff
+#define SHN_MIPS_ACCOMON 0xff00
+
+typedef struct {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct elf64_shdr {
+ Elf32_Word sh_name; /* Section name, index in string tbl (yes Elf32) */
+ Elf32_Word sh_type; /* Type of section (yes Elf32) */
+ Elf64_Word sh_flags; /* Miscellaneous section attributes */
+ Elf64_Addr sh_addr; /* Section virtual addr at execution */
+ Elf64_Off sh_offset; /* Section file offset */
+ Elf64_Word sh_size; /* Size of section in bytes */
+ Elf32_Word sh_link; /* Index of another section (yes Elf32) */
+ Elf32_Word sh_info; /* Additional section information (yes Elf32) */
+ Elf64_Word sh_addralign; /* Section alignment */
+ Elf64_Word sh_entsize; /* Entry size if section holds table */
+} Elf64_Shdr;
+
+#define EI_MAG0 0 /* e_ident[] indexes */
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_PAD 7
+
+#define ELFMAG0 0x7f /* EI_MAG */
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define ELFCLASSNONE 0 /* EI_CLASS */
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+#define ELFCLASSNUM 3
+
+#define ELFDATANONE 0 /* e_ident[EI_DATA] */
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+
+#define EV_NONE 0 /* e_version, EI_VERSION */
+#define EV_CURRENT 1
+#define EV_NUM 2
+
+/* Notes used in ET_CORE */
+#define NT_PRSTATUS 1
+#define NT_PRFPREG 2
+#define NT_PRPSINFO 3
+#define NT_TASKSTRUCT 4
+
+/* Note header in a PT_NOTE section */
+typedef struct elf32_note {
+ Elf32_Word n_namesz; /* Name size */
+ Elf32_Word n_descsz; /* Content size */
+ Elf32_Word n_type; /* Content type */
+} Elf32_Nhdr;
+
+/* Note header in a PT_NOTE section */
+/*
+ * For now we use the 32 bit version of the structure until we figure
+ * out whether we need anything better. Note - on the Alpha, "unsigned int"
+ * is only 32 bits.
+ */
+typedef struct elf64_note {
+ Elf32_Word n_namesz; /* Name size */
+ Elf32_Word n_descsz; /* Content size */
+ Elf32_Word n_type; /* Content type */
+} Elf64_Nhdr;
+
+#if ELF_CLASS == ELFCLASS32
+
+extern Elf32_Dyn _DYNAMIC [];
+#define elfhdr elf32_hdr
+#define elf_phdr elf32_phdr
+#define elf_note elf32_note
+
+#else
+
+extern Elf64_Dyn _DYNAMIC [];
+#define elfhdr elf64_hdr
+#define elf_phdr elf64_phdr
+#define elf_note elf64_note
+
+#endif
+
+
+#endif /* _LINUX_ELF_H */
--- /dev/null
+/*
+ * linux/include/linux/ext2_fs.h
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995
+ * Remy Card (card@masi.ibp.fr)
+ * Laboratoire MASI - Institut Blaise Pascal
+ * Universite Pierre et Marie Curie (Paris VI)
+ *
+ * from
+ *
+ * linux/include/linux/minix_fs.h
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+#ifndef _LINUX_EXT2_FS_H
+#define _LINUX_EXT2_FS_H
+
+#include "types.h"
+
+/*
+ * The second extended filesystem constants/structures
+ */
+
+/*
+ * Define EXT2FS_DEBUG to produce debug messages
+ */
+#undef EXT2FS_DEBUG
+
+/*
+ * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
+ */
+#define EXT2_PREALLOCATE
+#define EXT2_DEFAULT_PREALLOC_BLOCKS 8
+
+/*
+ * The second extended file system version
+ */
+#define EXT2FS_DATE "95/08/09"
+#define EXT2FS_VERSION "0.5b"
+
+/*
+ * Debug code
+ */
+#ifdef EXT2FS_DEBUG
+# define ext2_debug(f, a...) { \
+ printk ("EXT2-fs DEBUG (%s, %d): %s:", \
+ __FILE__, __LINE__, __FUNCTION__); \
+ printk (f, ## a); \
+ }
+#else
+# define ext2_debug(f, a...) /**/
+#endif
+
+/*
+ * Special inodes numbers
+ */
+#define EXT2_BAD_INO 1 /* Bad blocks inode */
+#define EXT2_ROOT_INO 2 /* Root inode */
+#define EXT2_ACL_IDX_INO 3 /* ACL inode */
+#define EXT2_ACL_DATA_INO 4 /* ACL inode */
+#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */
+#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */
+
+/* First non-reserved inode for old ext2 filesystems */
+#define EXT2_GOOD_OLD_FIRST_INO 11
+
+/*
+ * The second extended file system magic number
+ */
+#define EXT2_SUPER_MAGIC 0xEF53
+
+/*
+ * Maximal count of links to a file
+ */
+#define EXT2_LINK_MAX 32000
+
+/*
+ * Macro-instructions used to manage several block sizes
+ */
+#define EXT2_MIN_BLOCK_SIZE 1024
+#define EXT2_MAX_BLOCK_SIZE 4096
+#define EXT2_MIN_BLOCK_LOG_SIZE 10
+#ifdef __KERNEL__
+# define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize)
+#else
+# define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+#endif
+#define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
+#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+#ifdef __KERNEL__
+# define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits)
+#else
+# define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
+#endif
+#ifdef __KERNEL__
+#define EXT2_ADDR_PER_BLOCK_BITS(s) ((s)->u.ext2_sb.s_addr_per_block_bits)
+#define EXT2_INODE_SIZE(s) ((s)->u.ext2_sb.s_inode_size)
+#define EXT2_FIRST_INO(s) ((s)->u.ext2_sb.s_first_ino)
+#else
+#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+ EXT2_GOOD_OLD_INODE_SIZE : \
+ (s)->s_inode_size)
+#define EXT2_FIRST_INO(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+ EXT2_GOOD_OLD_FIRST_INO : \
+ (s)->s_first_ino)
+#endif
+
+/*
+ * Macro-instructions used to manage fragments
+ */
+#define EXT2_MIN_FRAG_SIZE 1024
+#define EXT2_MAX_FRAG_SIZE 4096
+#define EXT2_MIN_FRAG_LOG_SIZE 10
+#ifdef __KERNEL__
+# define EXT2_FRAG_SIZE(s) ((s)->u.ext2_sb.s_frag_size)
+# define EXT2_FRAGS_PER_BLOCK(s) ((s)->u.ext2_sb.s_frags_per_block)
+#else
+# define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
+# define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
+#endif
+
+/*
+ * ACL structures
+ */
+struct ext2_acl_header /* Header of Access Control Lists */
+{
+ __u32 aclh_size;
+ __u32 aclh_file_count;
+ __u32 aclh_acle_count;
+ __u32 aclh_first_acle;
+};
+
+struct ext2_acl_entry /* Access Control List Entry */
+{
+ __u32 acle_size;
+ __u16 acle_perms; /* Access permissions */
+ __u16 acle_type; /* Type of entry */
+ __u16 acle_tag; /* User or group identity */
+ __u16 acle_pad1;
+ __u32 acle_next; /* Pointer on next entry for the */
+ /* same inode or on next free entry */
+};
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext2_group_desc
+{
+ __u32 bg_block_bitmap; /* Blocks bitmap block */
+ __u32 bg_inode_bitmap; /* Inodes bitmap block */
+ __u32 bg_inode_table; /* Inodes table block */
+ __u16 bg_free_blocks_count; /* Free blocks count */
+ __u16 bg_free_inodes_count; /* Free inodes count */
+ __u16 bg_used_dirs_count; /* Directories count */
+ __u16 bg_pad;
+ __u32 bg_reserved[3];
+};
+
+/*
+ * Macro-instructions used to manage group descriptors
+ */
+#ifdef __KERNEL__
+# define EXT2_BLOCKS_PER_GROUP(s) ((s)->u.ext2_sb.s_blocks_per_group)
+# define EXT2_DESC_PER_BLOCK(s) ((s)->u.ext2_sb.s_desc_per_block)
+# define EXT2_INODES_PER_GROUP(s) ((s)->u.ext2_sb.s_inodes_per_group)
+# define EXT2_DESC_PER_BLOCK_BITS(s) ((s)->u.ext2_sb.s_desc_per_block_bits)
+#else
+# define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group)
+# define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
+# define EXT2_INODES_PER_GROUP(s) ((s)->s_inodes_per_group)
+#endif
+
+/*
+ * Constants relative to the data blocks
+ */
+#define EXT2_NDIR_BLOCKS 12
+#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
+#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
+#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
+#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
+
+/*
+ * Inode flags
+ */
+#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */
+#define EXT2_UNRM_FL 0x00000002 /* Undelete */
+#define EXT2_COMPR_FL 0x00000004 /* Compress file */
+#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
+#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
+#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
+#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
+#define EXT2_NOATIME_FL 0x00000080 /* do not update atime */
+/* Reserved for compression usage... */
+#define EXT2_DIRTY_FL 0x00000100
+#define EXT2_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */
+#define EXT2_NOCOMP_FL 0x00000400 /* Don't compress */
+#define EXT2_ECOMPR_FL 0x00000800 /* Compression error */
+/* End compression flags --- maybe not all used */
+#define EXT2_BTREE_FL 0x00001000 /* btree format dir */
+#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
+
+#define EXT2_FL_USER_VISIBLE 0x00001FFF /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE 0x000000FF /* User modifiable flags */
+
+/*
+ * ioctl commands
+ */
+#define EXT2_IOC_GETFLAGS _IOR('f', 1, long)
+#define EXT2_IOC_SETFLAGS _IOW('f', 2, long)
+#define EXT2_IOC_GETVERSION _IOR('v', 1, long)
+#define EXT2_IOC_SETVERSION _IOW('v', 2, long)
+
+/*
+ * Structure of an inode on the disk
+ */
+struct ext2_inode {
+ __u16 i_mode; /* File mode */
+ __u16 i_uid; /* Owner Uid */
+ __u32 i_size; /* Size in bytes */
+ __u32 i_atime; /* Access time */
+ __u32 i_ctime; /* Creation time */
+ __u32 i_mtime; /* Modification time */
+ __u32 i_dtime; /* Deletion Time */
+ __u16 i_gid; /* Group Id */
+ __u16 i_links_count; /* Links count */
+ __u32 i_blocks; /* Blocks count */
+ __u32 i_flags; /* File flags */
+ union {
+ struct {
+ __u32 l_i_reserved1;
+ } linux1;
+ struct {
+ __u32 h_i_translator;
+ } hurd1;
+ struct {
+ __u32 m_i_reserved1;
+ } masix1;
+ } osd1; /* OS dependent 1 */
+ __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+ __u32 i_version; /* File version (for NFS) */
+ __u32 i_file_acl; /* File ACL */
+ __u32 i_dir_acl; /* Directory ACL */
+ __u32 i_faddr; /* Fragment address */
+ union {
+ struct {
+ __u8 l_i_frag; /* Fragment number */
+ __u8 l_i_fsize; /* Fragment size */
+ __u16 i_pad1;
+ __u32 l_i_reserved2[2];
+ } linux2;
+ struct {
+ __u8 h_i_frag; /* Fragment number */
+ __u8 h_i_fsize; /* Fragment size */
+ __u16 h_i_mode_high;
+ __u16 h_i_uid_high;
+ __u16 h_i_gid_high;
+ __u32 h_i_author;
+ } hurd2;
+ struct {
+ __u8 m_i_frag; /* Fragment number */
+ __u8 m_i_fsize; /* Fragment size */
+ __u16 m_pad1;
+ __u32 m_i_reserved2[2];
+ } masix2;
+ } osd2; /* OS dependent 2 */
+};
+
+#define i_size_high i_dir_acl
+
+#if defined(__KERNEL__) || defined(__linux__)
+#define i_reserved1 osd1.linux1.l_i_reserved1
+#define i_frag osd2.linux2.l_i_frag
+#define i_fsize osd2.linux2.l_i_fsize
+#define i_reserved2 osd2.linux2.l_i_reserved2
+#endif
+
+#ifdef __hurd__
+#define i_translator osd1.hurd1.h_i_translator
+#define i_frag osd2.hurd2.h_i_frag;
+#define i_fsize osd2.hurd2.h_i_fsize;
+#define i_uid_high osd2.hurd2.h_i_uid_high
+#define i_gid_high osd2.hurd2.h_i_gid_high
+#define i_author osd2.hurd2.h_i_author
+#endif
+
+#ifdef __masix__
+#define i_reserved1 osd1.masix1.m_i_reserved1
+#define i_frag osd2.masix2.m_i_frag
+#define i_fsize osd2.masix2.m_i_fsize
+#define i_reserved2 osd2.masix2.m_i_reserved2
+#endif
+
+/*
+ * File system states
+ */
+#define EXT2_VALID_FS 0x0001 /* Unmounted cleanly */
+#define EXT2_ERROR_FS 0x0002 /* Errors detected */
+
+/*
+ * Mount flags
+ */
+#define EXT2_MOUNT_CHECK_NORMAL 0x0001 /* Do some more checks */
+#define EXT2_MOUNT_CHECK_STRICT 0x0002 /* Do again more checks */
+#define EXT2_MOUNT_CHECK (EXT2_MOUNT_CHECK_NORMAL | \
+ EXT2_MOUNT_CHECK_STRICT)
+#define EXT2_MOUNT_GRPID 0x0004 /* Create files with directory's group */
+#define EXT2_MOUNT_DEBUG 0x0008 /* Some debugging messages */
+#define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */
+#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */
+#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */
+#define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */
+
+#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
+#define set_opt(o, opt) o |= EXT2_MOUNT_##opt
+#define test_opt(sb, opt) ((sb)->u.ext2_sb.s_mount_opt & \
+ EXT2_MOUNT_##opt)
+/*
+ * Maximal mount counts between two filesystem checks
+ */
+#define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */
+#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */
+
+/*
+ * Behaviour when detecting errors
+ */
+#define EXT2_ERRORS_CONTINUE 1 /* Continue execution */
+#define EXT2_ERRORS_RO 2 /* Remount fs read-only */
+#define EXT2_ERRORS_PANIC 3 /* Panic */
+#define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE
+
+/*
+ * Structure of the super block
+ */
+struct ext2_super_block {
+ __u32 s_inodes_count; /* Inodes count */
+ __u32 s_blocks_count; /* Blocks count */
+ __u32 s_r_blocks_count; /* Reserved blocks count */
+ __u32 s_free_blocks_count; /* Free blocks count */
+ __u32 s_free_inodes_count; /* Free inodes count */
+ __u32 s_first_data_block; /* First Data Block */
+ __u32 s_log_block_size; /* Block size */
+ __s32 s_log_frag_size; /* Fragment size */
+ __u32 s_blocks_per_group; /* # Blocks per group */
+ __u32 s_frags_per_group; /* # Fragments per group */
+ __u32 s_inodes_per_group; /* # Inodes per group */
+ __u32 s_mtime; /* Mount time */
+ __u32 s_wtime; /* Write time */
+ __u16 s_mnt_count; /* Mount count */
+ __s16 s_max_mnt_count; /* Maximal mount count */
+ __u16 s_magic; /* Magic signature */
+ __u16 s_state; /* File system state */
+ __u16 s_errors; /* Behaviour when detecting errors */
+ __u16 s_minor_rev_level; /* minor revision level */
+ __u32 s_lastcheck; /* time of last check */
+ __u32 s_checkinterval; /* max. time between checks */
+ __u32 s_creator_os; /* OS */
+ __u32 s_rev_level; /* Revision level */
+ __u16 s_def_resuid; /* Default uid for reserved blocks */
+ __u16 s_def_resgid; /* Default gid for reserved blocks */
+ /*
+ * These fields are for EXT2_DYNAMIC_REV superblocks only.
+ *
+ * Note: the difference between the compatible feature set and
+ * the incompatible feature set is that if there is a bit set
+ * in the incompatible feature set that the kernel doesn't
+ * know about, it should refuse to mount the filesystem.
+ *
+ * e2fsck's requirements are more strict; if it doesn't know
+ * about a feature in either the compatible or incompatible
+ * feature set, it must abort and not try to meddle with
+ * things it doesn't understand...
+ */
+ __u32 s_first_ino; /* First non-reserved inode */
+ __u16 s_inode_size; /* size of inode structure */
+ __u16 s_block_group_nr; /* block group # of this superblock */
+ __u32 s_feature_compat; /* compatible feature set */
+ __u32 s_feature_incompat; /* incompatible feature set */
+ __u32 s_feature_ro_compat; /* readonly-compatible feature set */
+ __u8 s_uuid[16]; /* 128-bit uuid for volume */
+ char s_volume_name[16]; /* volume name */
+ char s_last_mounted[64]; /* directory where last mounted */
+ __u32 s_algorithm_usage_bitmap; /* For compression */
+ /*
+ * Performance hints. Directory preallocation should only
+ * happen if the EXT2_COMPAT_PREALLOC flag is on.
+ */
+ __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
+ __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
+ __u16 s_padding1;
+ __u32 s_reserved[204]; /* Padding to the end of the block */
+};
+
+#ifdef __KERNEL__
+#define EXT2_SB(sb) (&((sb)->u.ext2_sb))
+#else
+/* Assume that user mode programs are passing in an ext2fs superblock, not
+ * a kernel struct super_block. This will allow us to call the feature-test
+ * macros from user land. */
+#define EXT2_SB(sb) (sb)
+#endif
+
+/*
+ * Codes for operating systems
+ */
+#define EXT2_OS_LINUX 0
+#define EXT2_OS_HURD 1
+#define EXT2_OS_MASIX 2
+#define EXT2_OS_FREEBSD 3
+#define EXT2_OS_LITES 4
+
+/*
+ * Revision levels
+ */
+#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
+#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
+
+#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
+#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
+
+#define EXT2_GOOD_OLD_INODE_SIZE 128
+
+/*
+ * Feature set definitions
+ */
+
+#define EXT2_HAS_COMPAT_FEATURE(sb,mask) \
+ ( EXT2_SB(sb)->s_feature_compat & (mask) )
+#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \
+ ( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
+#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \
+ ( EXT2_SB(sb)->s_feature_incompat & (mask) )
+
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001
+
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
+
+#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001
+#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
+
+#define EXT2_FEATURE_COMPAT_SUPP 0
+#define EXT2_FEATURE_INCOMPAT_SUPP EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
+ EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+
+/*
+ * Default values for user and/or group using reserved blocks
+ */
+#define EXT2_DEF_RESUID 0
+#define EXT2_DEF_RESGID 0
+
+/*
+ * Structure of a directory entry
+ */
+#define EXT2_NAME_LEN 255
+
+struct ext2_dir_entry {
+ __u32 inode; /* Inode number */
+ __u16 rec_len; /* Directory entry length */
+ __u16 name_len; /* Name length */
+ char name[EXT2_NAME_LEN]; /* File name */
+};
+
+/*
+ * The new version of the directory entry. Since EXT2 structures are
+ * stored in intel byte order, and the name_len field could never be
+ * bigger than 255 chars, it's safe to reclaim the extra byte for the
+ * file_type field.
+ */
+struct ext2_dir_entry_2 {
+ __u32 inode; /* Inode number */
+ __u16 rec_len; /* Directory entry length */
+ __u8 name_len; /* Name length */
+ __u8 file_type;
+ char name[EXT2_NAME_LEN]; /* File name */
+};
+
+/*
+ * Ext2 directory file types. Only the low 3 bits are used. The
+ * other bits are reserved for now.
+ */
+#define EXT2_FT_UNKNOWN 0
+#define EXT2_FT_REG_FILE 1
+#define EXT2_FT_DIR 2
+#define EXT2_FT_CHRDEV 3
+#define EXT2_FT_BLKDEV 4
+#define EXT2_FT_FIFO 5
+#define EXT2_FT_SOCK 6
+#define EXT2_FT_SYMLINK 7
+
+#define EXT2_FT_MAX 8
+
+/*
+ * EXT2_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a multiple of 4
+ */
+#define EXT2_DIR_PAD 4
+#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1)
+#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
+ ~EXT2_DIR_ROUND)
+
+#ifdef __KERNEL__
+
+/* Filesize hard limits for 64-bit file offsets */
+extern long long ext2_max_sizes[];
+
+/*
+ * Function prototypes
+ */
+
+/*
+ * Ok, these declarations are also in <linux/kernel.h> but none of the
+ * ext2 source programs needs to include it so they are duplicated here.
+ */
+# define NORET_TYPE /**/
+# define ATTRIB_NORET __attribute__((noreturn))
+# define NORET_AND noreturn,
+
+/* acl.c */
+extern int ext2_permission (struct inode *, int);
+
+/* balloc.c */
+extern int ext2_group_sparse(int group);
+extern int ext2_new_block (const struct inode *, unsigned long,
+ __u32 *, __u32 *, int *);
+extern void ext2_free_blocks (const struct inode *, unsigned long,
+ unsigned long);
+extern unsigned long ext2_count_free_blocks (struct super_block *);
+extern void ext2_check_blocks_bitmap (struct super_block *);
+extern struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb,
+ unsigned int block_group,
+ struct buffer_head ** bh);
+
+/* bitmap.c */
+extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
+
+/* dir.c */
+extern int ext2_check_dir_entry (const char *, struct inode *,
+ struct ext2_dir_entry_2 *, struct buffer_head *,
+ unsigned long);
+
+/* file.c */
+extern int ext2_read (struct inode *, struct file *, char *, int);
+extern int ext2_write (struct inode *, struct file *, char *, int);
+
+/* fsync.c */
+extern int ext2_sync_file (struct file *, struct dentry *);
+
+/* ialloc.c */
+extern struct inode * ext2_new_inode (const struct inode *, int, int *);
+extern void ext2_free_inode (struct inode *);
+extern unsigned long ext2_count_free_inodes (struct super_block *);
+extern void ext2_check_inodes_bitmap (struct super_block *);
+
+/* inode.c */
+extern int ext2_bmap (struct inode *, int);
+
+extern struct buffer_head * ext2_getblk (struct inode *, long, int, int *);
+extern struct buffer_head * ext2_bread (struct inode *, int, int, int *);
+
+extern int ext2_getcluster (struct inode * inode, long block);
+extern void ext2_read_inode (struct inode *);
+extern void ext2_write_inode (struct inode *);
+extern void ext2_put_inode (struct inode *);
+extern void ext2_delete_inode (struct inode *);
+extern int ext2_sync_inode (struct inode *);
+extern int ext2_notify_change(struct dentry *, struct iattr *);
+extern void ext2_discard_prealloc (struct inode *);
+
+/* ioctl.c */
+extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
+ unsigned long);
+
+/* namei.c */
+extern void ext2_release (struct inode *, struct file *);
+extern struct dentry *ext2_lookup (struct inode *, struct dentry *);
+extern int ext2_create (struct inode *,struct dentry *,int);
+extern int ext2_mkdir (struct inode *,struct dentry *,int);
+extern int ext2_rmdir (struct inode *,struct dentry *);
+extern int ext2_unlink (struct inode *,struct dentry *);
+extern int ext2_symlink (struct inode *,struct dentry *,const char *);
+extern int ext2_link (struct dentry *, struct inode *, struct dentry *);
+extern int ext2_mknod (struct inode *, struct dentry *, int, int);
+extern int ext2_rename (struct inode *, struct dentry *,
+ struct inode *, struct dentry *);
+
+/* super.c */
+extern void ext2_error (struct super_block *, const char *, const char *, ...)
+ __attribute__ ((format (printf, 3, 4)));
+extern NORET_TYPE void ext2_panic (struct super_block *, const char *,
+ const char *, ...)
+ __attribute__ ((NORET_AND format (printf, 3, 4)));
+extern void ext2_warning (struct super_block *, const char *, const char *, ...)
+ __attribute__ ((format (printf, 3, 4)));
+extern void ext2_put_super (struct super_block *);
+extern void ext2_write_super (struct super_block *);
+extern int ext2_remount (struct super_block *, int *, char *);
+extern struct super_block * ext2_read_super (struct super_block *,void *,int);
+extern int init_ext2_fs(void);
+extern int ext2_statfs (struct super_block *, struct statfs *, int);
+
+/* truncate.c */
+extern void ext2_truncate (struct inode *);
+
+/*
+ * Inodes and files operations
+ */
+
+/* dir.c */
+extern struct inode_operations ext2_dir_inode_operations;
+
+/* file.c */
+extern struct inode_operations ext2_file_inode_operations;
+
+/* symlink.c */
+extern struct inode_operations ext2_symlink_inode_operations;
+
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_EXT2_FS_H */
--- /dev/null
+
+#ifndef _ISOFS_FS_H
+#define _ISOFS_FS_H
+
+#include <linux/types.h>
+/*
+ * The isofs filesystem constants/structures
+ */
+
+/* This part borrowed from the bsd386 isofs */
+#define ISODCL(from, to) (to - from + 1)
+
+struct iso_volume_descriptor {
+ char type[ISODCL(1,1)]; /* 711 */
+ char id[ISODCL(2,6)];
+ char version[ISODCL(7,7)];
+ char data[ISODCL(8,2048)];
+};
+
+/* volume descriptor types */
+#define ISO_VD_PRIMARY 1
+#define ISO_VD_SUPPLEMENTARY 2
+#define ISO_VD_END 255
+
+#define ISO_STANDARD_ID "CD001"
+
+struct iso_primary_descriptor {
+ char type [ISODCL ( 1, 1)]; /* 711 */
+ char id [ISODCL ( 2, 6)];
+ char version [ISODCL ( 7, 7)]; /* 711 */
+ char unused1 [ISODCL ( 8, 8)];
+ char system_id [ISODCL ( 9, 40)]; /* achars */
+ char volume_id [ISODCL ( 41, 72)]; /* dchars */
+ char unused2 [ISODCL ( 73, 80)];
+ char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
+ char unused3 [ISODCL ( 89, 120)];
+ char volume_set_size [ISODCL (121, 124)]; /* 723 */
+ char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
+ char logical_block_size [ISODCL (129, 132)]; /* 723 */
+ char path_table_size [ISODCL (133, 140)]; /* 733 */
+ char type_l_path_table [ISODCL (141, 144)]; /* 731 */
+ char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
+ char type_m_path_table [ISODCL (149, 152)]; /* 732 */
+ char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
+ char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
+ char volume_set_id [ISODCL (191, 318)]; /* dchars */
+ char publisher_id [ISODCL (319, 446)]; /* achars */
+ char preparer_id [ISODCL (447, 574)]; /* achars */
+ char application_id [ISODCL (575, 702)]; /* achars */
+ char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
+ char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
+ char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
+ char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
+ char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
+ char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
+ char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
+ char file_structure_version [ISODCL (882, 882)]; /* 711 */
+ char unused4 [ISODCL (883, 883)];
+ char application_data [ISODCL (884, 1395)];
+ char unused5 [ISODCL (1396, 2048)];
+};
+
+/* Almost the same as the primary descriptor but two fields are specified */
+struct iso_supplementary_descriptor {
+ char type [ISODCL ( 1, 1)]; /* 711 */
+ char id [ISODCL ( 2, 6)];
+ char version [ISODCL ( 7, 7)]; /* 711 */
+ char flags [ISODCL ( 8, 8)]; /* 853 */
+ char system_id [ISODCL ( 9, 40)]; /* achars */
+ char volume_id [ISODCL ( 41, 72)]; /* dchars */
+ char unused2 [ISODCL ( 73, 80)];
+ char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
+ char escape [ISODCL ( 89, 120)]; /* 856 */
+ char volume_set_size [ISODCL (121, 124)]; /* 723 */
+ char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
+ char logical_block_size [ISODCL (129, 132)]; /* 723 */
+ char path_table_size [ISODCL (133, 140)]; /* 733 */
+ char type_l_path_table [ISODCL (141, 144)]; /* 731 */
+ char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
+ char type_m_path_table [ISODCL (149, 152)]; /* 732 */
+ char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
+ char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
+ char volume_set_id [ISODCL (191, 318)]; /* dchars */
+ char publisher_id [ISODCL (319, 446)]; /* achars */
+ char preparer_id [ISODCL (447, 574)]; /* achars */
+ char application_id [ISODCL (575, 702)]; /* achars */
+ char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
+ char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
+ char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
+ char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
+ char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
+ char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
+ char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
+ char file_structure_version [ISODCL (882, 882)]; /* 711 */
+ char unused4 [ISODCL (883, 883)];
+ char application_data [ISODCL (884, 1395)];
+ char unused5 [ISODCL (1396, 2048)];
+};
+
+
+#define HS_STANDARD_ID "CDROM"
+
+struct hs_volume_descriptor {
+ char foo [ISODCL ( 1, 8)]; /* 733 */
+ char type [ISODCL ( 9, 9)]; /* 711 */
+ char id [ISODCL ( 10, 14)];
+ char version [ISODCL ( 15, 15)]; /* 711 */
+ char data[ISODCL(16,2048)];
+};
+
+
+struct hs_primary_descriptor {
+ char foo [ISODCL ( 1, 8)]; /* 733 */
+ char type [ISODCL ( 9, 9)]; /* 711 */
+ char id [ISODCL ( 10, 14)];
+ char version [ISODCL ( 15, 15)]; /* 711 */
+ char unused1 [ISODCL ( 16, 16)]; /* 711 */
+ char system_id [ISODCL ( 17, 48)]; /* achars */
+ char volume_id [ISODCL ( 49, 80)]; /* dchars */
+ char unused2 [ISODCL ( 81, 88)]; /* 733 */
+ char volume_space_size [ISODCL ( 89, 96)]; /* 733 */
+ char unused3 [ISODCL ( 97, 128)]; /* 733 */
+ char volume_set_size [ISODCL (129, 132)]; /* 723 */
+ char volume_sequence_number [ISODCL (133, 136)]; /* 723 */
+ char logical_block_size [ISODCL (137, 140)]; /* 723 */
+ char path_table_size [ISODCL (141, 148)]; /* 733 */
+ char type_l_path_table [ISODCL (149, 152)]; /* 731 */
+ char unused4 [ISODCL (153, 180)]; /* 733 */
+ char root_directory_record [ISODCL (181, 214)]; /* 9.1 */
+};
+
+/* We use this to help us look up the parent inode numbers. */
+
+struct iso_path_table{
+ unsigned char name_len[2]; /* 721 */
+ char extent[4]; /* 731 */
+ char parent[2]; /* 721 */
+ char name[0];
+};
+
+/* high sierra is identical to iso, except that the date is only 6 bytes, and
+ there is an extra reserved byte after the flags */
+
+struct iso_directory_record {
+ char length [ISODCL (1, 1)]; /* 711 */
+ char ext_attr_length [ISODCL (2, 2)]; /* 711 */
+ char extent [ISODCL (3, 10)]; /* 733 */
+ char size [ISODCL (11, 18)]; /* 733 */
+ char date [ISODCL (19, 25)]; /* 7 by 711 */
+ char flags [ISODCL (26, 26)];
+ char file_unit_size [ISODCL (27, 27)]; /* 711 */
+ char interleave [ISODCL (28, 28)]; /* 711 */
+ char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
+ unsigned char name_len [ISODCL (33, 33)]; /* 711 */
+ char name [0];
+};
+
+#define ISOFS_BLOCK_BITS 11
+#define ISOFS_BLOCK_SIZE 2048
+
+#define ISOFS_BUFFER_SIZE(INODE) ((INODE)->i_sb->s_blocksize)
+#define ISOFS_BUFFER_BITS(INODE) ((INODE)->i_sb->s_blocksize_bits)
+#define ISOFS_ZONE_BITS(INODE) ((INODE)->i_sb->u.isofs_sb.s_log_zone_size)
+
+#define ISOFS_SUPER_MAGIC 0x9660
+
+extern int isonum_711(char *);
+extern int isonum_712(char *);
+extern int isonum_721(char *);
+extern int isonum_722(char *);
+extern int isonum_723(char *);
+extern int isonum_731(char *);
+extern int isonum_732(char *);
+extern int isonum_733(char *);
+
+
+#endif
--- /dev/null
+#ifndef _LINUX_STAT_H
+#define _LINUX_STAT_H
+
+#define S_IFMT 00170000
+#define S_IFSOCK 0140000
+#define S_IFLNK 0120000
+#define S_IFREG 0100000
+#define S_IFBLK 0060000
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFIFO 0010000
+#define S_ISUID 0004000
+#define S_ISGID 0002000
+#define S_ISVTX 0001000
+
+#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+
+#define S_IRWXU 00700
+#define S_IRUSR 00400
+#define S_IWUSR 00200
+#define S_IXUSR 00100
+
+#define S_IRWXG 00070
+#define S_IRGRP 00040
+#define S_IWGRP 00020
+#define S_IXGRP 00010
+
+#define S_IRWXO 00007
+#define S_IROTH 00004
+#define S_IWOTH 00002
+#define S_IXOTH 00001
+
+#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
+#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
+#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
+#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
+#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
+
+#endif
--- /dev/null
+#include "../types.h"
\ No newline at end of file
--- /dev/null
+/*
+ * Structure of a Macintosh driver descriptor (block 0)
+ * and partition table (blocks 1..n).
+ *
+ * Copyright 1996 Paul Mackerras.
+ */
+
+#define MAC_PARTITION_MAGIC 0x504d
+
+/* type field value for A/UX or other Unix partitions */
+#define APPLE_AUX_TYPE "Apple_UNIX_SVR2"
+
+struct mac_partition {
+ __u16 signature; /* expected to be MAC_PARTITION_MAGIC */
+ __u16 res1;
+ __u32 map_count; /* # blocks in partition map */
+ __u32 start_block; /* absolute starting block # of partition */
+ __u32 block_count; /* number of blocks in partition */
+ char name[32]; /* partition name */
+ char type[32]; /* string type description */
+ __u32 data_start; /* rel block # of first data block */
+ __u32 data_count; /* number of data blocks */
+ __u32 status; /* partition status */
+ __u32 boot_start; /* logical start block no. of bootstrap */
+ __u32 boot_size; /* no. of bytes in bootstrap */
+ __u32 boot_load; /* bootstrap load address in memory */
+ __u32 boot_load2; /* reserved for extension of boot_load */
+ __u32 boot_entry; /* entry point address for bootstrap */
+ __u32 boot_entry2; /* reserved for extension of boot_entry */
+ __u32 boot_cksum;
+ char processor[16]; /* name of processor that boot is for */
+};
+
+/* Bit in status field */
+#define STATUS_BOOTABLE 8 /* partition is bootable */
+
+#define MAC_DRIVER_MAGIC 0x4552
+
+/* Driver descriptor structure, in block 0 */
+struct mac_driver_desc {
+ __u16 signature; /* expected to be MAC_DRIVER_MAGIC */
+ __u16 block_size;
+ __u32 block_count;
+ /* ... more stuff */
+};
--- /dev/null
+/* md5.h - an implementation of the MD5 algorithm and MD5 crypt */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* If CHECK is true, check a password for correctness. Returns 0
+ if password was correct, and a value != 0 for error, similarly
+ to strcmp.
+ If CHECK is false, crypt KEY and save the result in CRYPTED.
+ CRYPTED must have a salt. */
+extern int md5_password (const char *key, char *crypted, int check);
+
+/* For convenience. */
+#define check_md5_password(key,crypted) md5_password((key), (crypted), 1)
+#define make_md5_password(key,crypted) md5_password((key), (crypted), 0)
--- /dev/null
+/*
+ Partition map management
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef PARTITION_H
+#define PARTITION_H
+
+struct partition_t;
+
+#include "types.h"
+#include "stddef.h"
+#include "prom.h"
+
+#define MAX_PARTITIONS 32
+#define MAX_PART_NAME 32
+
+struct partition_t {
+ struct partition_t* next;
+ int part_number;
+ char part_name[MAX_PART_NAME];
+ unsigned long part_start; /* In blocks */
+ unsigned long part_size; /* In blocks */
+ unsigned short blocksize;
+};
+
+extern struct partition_t* partitions_lookup(const char *device);
+extern void partitions_free(struct partition_t* list);
+
+
+
+#endif
--- /dev/null
+/*
+ Definitions for talking to the Open Firmware PROM on
+ Power Macintosh computers.
+
+ Copyright (C) 1999 Marius Vollmer
+ Copyright (C) 1996 Paul Mackerras.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef PROM_H
+#define PROM_H
+
+#include "stdarg.h"
+
+typedef void *prom_handle;
+typedef void *ihandle;
+typedef void *phandle;
+
+#define PROM_INVALID_HANDLE ((prom_handle)-1UL)
+
+struct prom_args;
+typedef int (*prom_entry)(struct prom_args *);
+
+extern void prom_init (prom_entry pe);
+
+extern prom_entry prom;
+
+/* I/O */
+
+extern prom_handle prom_stdin;
+extern prom_handle prom_stdout;
+
+prom_handle prom_open (char *spec);
+int prom_read (prom_handle file, void *buf, int len);
+int prom_write (prom_handle file, void *buf, int len);
+int prom_seek (prom_handle file, int pos);
+int prom_lseek (prom_handle file, unsigned long long pos);
+int prom_readblocks (prom_handle file, int blockNum, int blockCount, void *buffer);
+void prom_close (prom_handle file);
+int prom_getblksize (prom_handle file);
+int prom_loadmethod (prom_handle device, void* addr);
+
+#define K_UP 0x141
+#define K_DOWN 0x142
+#define K_LEFT 0x144
+#define K_RIGHT 0x143
+
+int prom_getchar ();
+void prom_putchar (char);
+int prom_nbgetchar();
+
+void prom_vprintf (char *fmt, va_list ap);
+void prom_fprintf (prom_handle dev, char *fmt, ...);
+void prom_printf (char *fmt, ...);
+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 */
+
+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);
+
+/* packages and device nodes */
+
+prom_handle prom_finddevice (char *name);
+prom_handle prom_findpackage (char *path);
+int prom_getprop (prom_handle dev, char *name, void *buf, int len);
+
+/* misc */
+
+char *prom_getargs ();
+void prom_setargs (char *args);
+
+void prom_exit ();
+void prom_abort (char *fmt, ...);
+
+int prom_interpret (char *forth);
+
+int prom_get_chosen (char *name, void *mem, int len);
+int prom_get_options (char *name, void *mem, int len);
+
+extern int prom_getms(void);
+extern void prom_pause(void);
+
+extern void *call_prom (const char *service, int nargs, int nret, ...);
+extern void *call_prom_return (const char *service, int nargs, int nret, ...);
+
+#endif
--- /dev/null
+#ifndef _REISERFS_H_
+#define _REISERFS_H_
+#include "byteorder.h"
+#include "types.h"
+
+/* ReiserFS Super Block */
+/* include/linux/reiserfs_fs_sb.h */
+#define REISERFS_MAX_SUPPORTED_VERSION 2
+#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
+#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
+#define REISERFS_MAX_TREE_HEIGHT 7
+
+struct reiserfs_super_block
+{
+ __u32 s_block_count;
+ __u32 s_free_blocks; /* free blocks count */
+ __u32 s_root_block; /* root block number */
+ __u32 s_journal_block; /* journal block number */
+ __u32 s_journal_dev; /* journal device number */
+ __u32 s_orig_journal_size; /* size of the journal */
+ __u32 s_journal_trans_max; /* max number of blocks in
+ a transaction. */
+ __u32 s_journal_block_count; /* total size of the journal.
+ can change over time */
+ __u32 s_journal_max_batch; /* max number of blocks to
+ batch into a trans */
+ __u32 s_journal_max_commit_age; /* in seconds, how old can an
+ async commit be */
+ __u32 s_journal_max_trans_age; /* in seconds, how old can a
+ transaction be */
+ __u16 s_blocksize; /* block size */
+ __u16 s_oid_maxsize; /* max size of object id array, */
+ __u16 s_oid_cursize; /* current size of obj id array */
+ __u16 s_state; /* valid or error */
+ char s_magic[12]; /* reiserfs magic string indicates
+ that file system is reiserfs */
+ __u32 s_hash_function_code; /* indicate, what hash function is
+ being use to sort names in a
+ directory */
+ __u16 s_tree_height; /* height of disk tree */
+ __u16 s_bmap_nr; /* amount of bitmap blocks needed
+ to address each block of file
+ system */
+ __u16 s_version;
+ __u16 s_marked_in_use;
+ __u16 s_inode_generation;
+ char s_unused[124]; /* zero filled by mkreiserfs */
+ char padding_to_quad[ 2 ]; /* aligned to __u32 */
+} __attribute__ ((__packed__));
+#define SB_SIZE (sizeof (struct reiserfs_super_block) )
+
+/* ReiserFS Journal */
+/* include/linux/reiserfs_fs.h */
+/* must be correct to keep the desc and commit structs at 4k */
+#define JOURNAL_TRANS_HALF 1018
+
+/* first block written in a commit */
+struct reiserfs_journal_desc {
+ __u32 j_trans_id; /* id of commit */
+ __u32 j_len; /* length of commit. len +1 is the
+ commit block */
+ __u32 j_mount_id; /* mount id of this trans*/
+ __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for each block */
+ char j_magic[12];
+};
+
+/* last block written in a commit */
+struct reiserfs_journal_commit {
+ __u32 j_trans_id; /* must match j_trans_id from the
+ desc block */
+ __u32 j_len; /* ditto */
+ __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for each block */
+ char j_digest[16]; /* md5 sum of all the blocks
+ involved, including desc and
+ commit. not used, kill it */
+};
+
+/*
+** This header block gets written whenever a transaction is considered
+** fully flushed, and is more recent than the last fully flushed
+** transaction. fully flushed means all the log blocks and all the real
+** blocks are on disk, and this transaction does not need to be replayed.
+*/
+struct reiserfs_journal_header {
+ __u32 j_last_flush_trans_id; /* id of last fully flushed transaction */
+ __u32 j_first_unflushed_offset; /* offset in the log of where to start
+ replay after a crash */
+ __u32 j_mount_id;
+};
+
+/* Magic to find journal descriptors */
+#define JOURNAL_DESC_MAGIC "ReIsErLB"
+
+/* ReiserFS Tree structures/accessors */
+/* Item version determines which offset_v# struct to use */
+#define ITEM_VERSION_1 0
+#define ITEM_VERSION_2 1
+#define IH_KEY_OFFSET(ih) (INFO->version < 2 \
+ || ih_version(ih) == ITEM_VERSION_1 \
+ ? (ih)->ih_key.u.k_offset_v1.k_offset \
+ : offset_v2_k_offset(&(ih)->ih_key.u.k_offset_v2))
+
+#define IH_KEY_ISTYPE(ih, type) (INFO->version < 2 \
+ || ih_version(ih) == ITEM_VERSION_1 \
+ ? (ih)->ih_key.u.k_offset_v1.k_uniqueness == V1_##type \
+ : offset_v2_k_type(&(ih)->ih_key.u.k_offset_v2) == V2_##type)
+
+//
+// directories use this key as well as old files
+//
+struct offset_v1 {
+ __u32 k_offset;
+ __u32 k_uniqueness;
+} __attribute__ ((__packed__));
+
+struct offset_v2 {
+#ifdef __LITTLE_ENDIAN
+ /* little endian version */
+ __u64 k_offset:60;
+ __u64 k_type: 4;
+#else
+ /* big endian version */
+ __u64 k_type: 4;
+ __u64 k_offset:60;
+#endif
+} __attribute__ ((__packed__));
+
+#ifndef __LITTLE_ENDIAN
+inline __u16 offset_v2_k_type( struct offset_v2 *v2 );
+inline loff_t offset_v2_k_offset( struct offset_v2 *v2 );
+#else
+# define offset_v2_k_type(v2) ((v2)->k_type)
+# define offset_v2_k_offset(v2) ((v2)->k_offset)
+#endif
+
+/* Key of an item determines its location in the S+tree, and
+ is composed of 4 components */
+struct key {
+ __u32 k_dir_id; /* packing locality: by default parent
+ directory object id */
+ __u32 k_objectid; /* object identifier */
+ union {
+ struct offset_v1 k_offset_v1;
+ struct offset_v2 k_offset_v2;
+ } __attribute__ ((__packed__)) u;
+} __attribute__ ((__packed__));
+#define KEY_SIZE (sizeof (struct key))
+
+//
+// there are 5 item types currently
+//
+#define TYPE_STAT_DATA 0
+#define TYPE_INDIRECT 1
+#define TYPE_DIRECT 2
+#define TYPE_DIRENTRY 3
+#define TYPE_ANY 15 // FIXME: comment is required
+
+//
+// in old version uniqueness field shows key type
+//
+#define V1_SD_UNIQUENESS 0
+#define V1_INDIRECT_UNIQUENESS 0xfffffffe
+#define V1_DIRECT_UNIQUENESS 0xffffffff
+#define V1_DIRENTRY_UNIQUENESS 500
+#define V1_ANY_UNIQUENESS 555 // FIXME: comment is required
+inline int uniqueness2type (__u32 uniqueness);
+
+struct item_head
+{
+ struct key ih_key; /* Everything in the tree is found by
+ searching for its key.*/
+
+ union {
+ __u16 ih_free_space_reserved; /* The free space in the last unformatted
+ node of an indirect item if this is an
+ indirect item. This equals 0xFFFF
+ iff this is a direct item or stat
+ data item. Note that the key, not
+ this field, is used to determine
+ the item type, and thus which field
+ this union contains. */
+ __u16 ih_entry_count; /* Iff this is a directory item, this
+ field equals the number of directory
+ entries in the directory item. */
+ } __attribute__ ((__packed__)) u;
+ __u16 ih_item_len; /* total size of the item body */
+ __u16 ih_item_location; /* Offset to the item within the block */
+ __u16 ih_version; /* ITEM_VERSION_[01] of key type */
+} __attribute__ ((__packed__));
+#define IH_SIZE (sizeof(struct item_head))
+
+#define ih_version(ih) le16_to_cpu((ih)->ih_version)
+#define ih_entry_count(ih) le16_to_cpu((ih)->u.ih_entry_count)
+#define ih_location(ih) le16_to_cpu((ih)->ih_item_location)
+#define ih_item_len(ih) le16_to_cpu((ih)->ih_item_len)
+
+/* Header of a disk block. More precisely, header of a formatted leaf
+ or internal node, and not the header of an unformatted node. */
+struct block_head {
+ __u16 blk_level; /* Level of a block in the tree */
+ __u16 blk_nr_item; /* Number of keys/items in a block */
+ __u16 blk_free_space; /* Block free space in bytes */
+ __u16 blk_reserved;
+ struct key blk_right_delim_key; /* kept only for compatibility */
+};
+#define BLKH_SIZE (sizeof(struct block_head))
+
+#define blkh_level(p_blkh) (le16_to_cpu((p_blkh)->blk_level))
+#define blkh_nr_item(p_blkh) (le16_to_cpu((p_blkh)->blk_nr_item))
+
+#define BLKH_LEVEL_FREE 0 /* Freed from the tree */
+#define BLKH_LEVEL_LEAF 1 /* Leaf node level*/
+
+struct disk_child {
+ __u32 dc_block_number; /* Disk child's block number */
+ __u16 dc_size; /* Disk child's used space */
+ __u16 dc_reserved;
+};
+
+#define DC_SIZE (sizeof(struct disk_child))
+#define dc_block_number(dc_p) (le32_to_cpu((dc_p)->dc_block_number))
+#define dc_size(dc_p) (le16_to_cpu((dc_p)->dc_size))
+
+/* Stat data */
+struct stat_data_v1
+{
+ __u16 sd_mode; /* file type, permissions */
+ __u16 sd_nlink; /* number of hard links */
+ __u16 sd_uid; /* owner */
+ __u16 sd_gid; /* group */
+ __u32 sd_size; /* file size */
+ __u32 sd_atime; /* time of last access */
+ __u32 sd_mtime; /* time file was last modified */
+ __u32 sd_ctime; /* time inode (stat data) was last changed
+ (except changes to sd_atime and sd_mtime) */
+ union {
+ __u32 sd_rdev;
+ __u32 sd_blocks; /* number of blocks file uses */
+ } __attribute__ ((__packed__)) u;
+ __u32 sd_first_direct_byte; /* 0 = no direct item, 1 = symlink */
+} __attribute__ ((__packed__));
+#define SD_V1_SIZE (sizeof(struct stat_data_v1))
+
+#define stat_data_v1(ih) (ih_version (ih) == ITEM_VERSION_1)
+#define sd_v1_size(sdp) (le32_to_cpu((sdp)->sd_size))
+
+/* Stat Data on disk (reiserfs version of UFS disk inode minus the
+ address blocks) */
+struct stat_data {
+ __u16 sd_mode; /* file type, permissions */
+ __u16 sd_reserved;
+ __u32 sd_nlink; /* number of hard links */
+ __u64 sd_size; /* file size */
+ __u32 sd_uid; /* owner */
+ __u32 sd_gid; /* group */
+ __u32 sd_atime; /* time of last access */
+ __u32 sd_mtime; /* time file was last modified */
+ __u32 sd_ctime; /* time inode (stat data) was last changed
+ (except changes to sd_atime and sd_mtime) */
+ __u32 sd_blocks;
+ __u32 sd_rdev;
+} __attribute__ ((__packed__));
+#define SD_V2_SIZE (sizeof(struct stat_data))
+#define stat_data_v2(ih) (ih_version (ih) == ITEM_VERSION_2)
+#define sd_v2_size(sdp) (le64_to_cpu((sdp)->sd_size))
+
+/* valid for any stat data */
+#define sd_size(ih,sdp) ((ih_version(ih) == ITEM_VERSION_2) ? \
+ sd_v2_size((struct stat_data *)sdp) : \
+ sd_v1_size((struct stat_data_v1 *)sdp))
+#define sd_mode(sdp) (le16_to_cpu((sdp)->sd_mode))
+
+struct reiserfs_de_head
+{
+ __u32 deh_offset; /* third component of the directory entry key */
+ __u32 deh_dir_id; /* objectid of the parent directory of the object,
+ that is referenced by directory entry */
+ __u32 deh_objectid; /* objectid of the object, that is referenced by
+ directory entry */
+ __u16 deh_location; /* offset of name in the whole item */
+ __u16 deh_state; /* whether 1) entry contains stat data (for future), and 2) whether entry is hidden (unlinked) */
+} __attribute__ ((__packed__));
+#define DEH_SIZE sizeof(struct reiserfs_de_head)
+
+#define deh_offset(p_deh) (le32_to_cpu((p_deh)->deh_offset))
+#define deh_dir_id(p_deh) (le32_to_cpu((p_deh)->deh_dir_id))
+#define deh_objectid(p_deh) (le32_to_cpu((p_deh)->deh_objectid))
+#define deh_location(p_deh) (le16_to_cpu((p_deh)->deh_location))
+#define deh_state(p_deh) (le16_to_cpu((p_deh)->deh_state))
+
+/* empty directory contains two entries "." and ".." and their headers */
+#define EMPTY_DIR_SIZE \
+(DEH_SIZE * 2 + ROUND_UP (strlen (".")) + ROUND_UP (strlen ("..")))
+
+/* old format directories have this size when empty */
+#define EMPTY_DIR_SIZE_V1 (DEH_SIZE * 2 + 3)
+
+#define DEH_Statdata 0 /* not used now */
+#define DEH_Visible 2
+
+/* 64 bit systems need to aligned explicitly -jdm */
+#if BITS_PER_LONG == 64
+# define ADDR_UNALIGNED_BITS (5)
+#endif
+
+#define test_bit(x,y) ext2fs_test_bit(x,y)
+
+#ifdef ADDR_UNALIGNED_BITS
+# define aligned_address(addr) ((void *)((long)(addr) & ~((1UL << ADDR_UNALIGNED_BITS) - 1)))
+# define unaligned_offset(addr) (((int)((long)(addr) & ((1 << ADDR_UNALIGNED_BITS) - 1))) << 3)
+# define set_bit_unaligned(nr, addr) set_bit((nr) + unaligned_offset(addr), aligned_address(addr))
+# define clear_bit_unaligned(nr, addr) clear_bit((nr) + unaligned_offset(addr), aligned_address(addr))
+# define test_bit_unaligned(nr, addr) test_bit((nr) + unaligned_offset(addr), aligned_address(addr))
+#else
+# define set_bit_unaligned(nr, addr) set_bit(nr, addr)
+# define clear_bit_unaligned(nr, addr) clear_bit(nr, addr)
+# define test_bit_unaligned(nr, addr) test_bit(nr, addr)
+#endif
+
+#define SD_OFFSET 0
+#define SD_UNIQUENESS 0
+#define DOT_OFFSET 1
+#define DOT_DOT_OFFSET 2
+#define DIRENTRY_UNIQUENESS 500
+
+#define V1_TYPE_STAT_DATA 0x0
+#define V1_TYPE_DIRECT 0xffffffff
+#define V1_TYPE_INDIRECT 0xfffffffe
+#define V1_TYPE_DIRECTORY_MAX 0xfffffffd
+#define V2_TYPE_STAT_DATA 0
+#define V2_TYPE_INDIRECT 1
+#define V2_TYPE_DIRECT 2
+#define V2_TYPE_DIRENTRY 3
+
+
+#define REISERFS_ROOT_OBJECTID 2
+#define REISERFS_ROOT_PARENT_OBJECTID 1
+#define REISERFS_SUPERBLOCK_BLOCK 16
+/* the spot for the super in versions 3.5 - 3.5.11 (inclusive) */
+#define REISERFS_OLD_SUPERBLOCK_BLOCK 2
+#define REISERFS_OLD_BLOCKSIZE 4096
+
+#define S_ISREG(mode) (((mode) & 0170000) == 0100000)
+#define S_ISDIR(mode) (((mode) & 0170000) == 0040000)
+#define S_ISLNK(mode) (((mode) & 0170000) == 0120000)
+#define PATH_MAX 1024 /* include/linux/limits.h */
+#define MAX_LINK_COUNT 5 /* number of symbolic links to follow */
+
+/* Cache stuff, adapted from GRUB source */
+#define FSYSREISER_CACHE_SIZE (REISERFS_MAX_TREE_HEIGHT*REISERFS_OLD_BLOCKSIZE)
+#define SECTOR_SIZE 512
+#define FSYSREISER_MIN_BLOCKSIZE SECTOR_SIZE
+#define FSYSREISER_MAX_BLOCKSIZE FSYSREISER_CACHE_SIZE / 3
+
+
+struct reiserfs_state
+{
+ /* Context */
+ struct key fileinfo;
+ struct boot_file_t *file;
+ struct item_head *current_ih;
+ char *current_item;
+ __u64 partition_offset;
+
+ /* Commonly used values, cpu order */
+ __u32 journal_block; /* Start of journal */
+ __u32 journal_block_count; /* The size of the journal */
+ __u32 journal_first_desc; /* The first valid descriptor block in journal
+ (relative to journal_block) */
+
+ __u16 version; /* The ReiserFS version. */
+ __u16 tree_depth; /* The current depth of the reiser tree. */
+ __u8 blocksize_shift; /* 1 << blocksize_shift == blocksize. */
+ __u16 blocksize; /* The reiserfs block size (power of 2) */
+
+ /* Cache */
+ __u16 cached_slots;
+ __u16 journal_transactions;
+ __u32 blocks[REISERFS_MAX_TREE_HEIGHT];
+ __u32 next_key_nr[REISERFS_MAX_TREE_HEIGHT];
+};
+
+#define ROOT ((char *)FSYS_BUF)
+#define CACHE(i) (ROOT + ((i) * INFO->blocksize))
+#define LEAF CACHE (BLKH_LEVEL_LEAF)
+
+#define BLOCKHEAD(cache) ((struct block_head *) cache)
+#define ITEMHEAD ((struct item_head *) ((int) LEAF + BLKH_SIZE))
+#define KEY(cache) ((struct key *) ((int) cache + BLKH_SIZE))
+#define DC(cache) ((struct disk_child *) \
+ ((int) cache + BLKH_SIZE + KEY_SIZE * nr_item))
+
+/*
+ * The journal cache. For each transaction it contains the number of
+ * blocks followed by the real block numbers of this transaction.
+ *
+ * If the block numbers of some transaction won't fit in this space,
+ * this list is stopped with a 0xffffffff marker and the remaining
+ * uncommitted transactions aren't cached.
+ */
+#define JOURNAL_START ((__u32 *) (FSYS_BUF + FSYSREISER_CACHE_SIZE))
+#define JOURNAL_END ((__u32 *) (FSYS_BUF + sizeof(FSYS_BUF)))
+
+
+#endif /* _REISERFS_H_ */
--- /dev/null
+/* Copyright (C) 1991,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/*
+ * ISO C Standard: 4.6 NON-LOCAL JUMPS <setjmp.h>
+ */
+
+#ifndef _SETJMP_H
+#define _SETJMP_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+#include <bits/setjmp.h> /* Get `__jmp_buf'. */
+#include <bits/sigset.h> /* Get `__sigset_t'. */
+
+/* Calling environment, plus possibly a saved signal mask. */
+typedef struct __jmp_buf_tag /* C++ doesn't like tagless structs. */
+ {
+ /* NOTE: The machine-dependent definitions of `__sigsetjmp'
+ assume that a `jmp_buf' begins with a `__jmp_buf'.
+ Do not move this member or add others before it. */
+ __jmp_buf __jmpbuf; /* Calling environment. */
+ int __mask_was_saved; /* Saved the signal mask? */
+ __sigset_t __saved_mask; /* Saved signal mask. */
+ } jmp_buf[1];
+
+
+/* Store the calling environment in ENV, also saving the
+ signal mask if SAVEMASK is nonzero. Return 0.
+ This is the internal name for `sigsetjmp'. */
+extern int __sigsetjmp __P ((jmp_buf __env, int __savemask));
+
+#ifndef __FAVOR_BSD
+/* Set ENV to the current position and return 0, not saving the signal mask.
+ This is just like `sigsetjmp (ENV, 0)'.
+ The ISO C standard says `setjmp' is a macro. */
+# define setjmp(env) __sigsetjmp ((env), 0)
+#else
+/* We are in 4.3 BSD-compatibility mode in which `setjmp'
+ saves the signal mask like `sigsetjmp (ENV, 1)'. */
+# define setjmp(env) __sigsetjmp ((env), 1)
+#endif /* Favor BSD. */
+
+#if defined __USE_BSD || defined __USE_XOPEN
+/* Set ENV to the current position and return 0, not saving the signal mask.
+ This is the 4.3 BSD name for ISO `setjmp'. */
+# define _setjmp(env) __sigsetjmp ((env), 0)
+#endif
+
+
+/* Jump to the environment saved in ENV, making the
+ `setjmp' call there return VAL, or 1 if VAL is 0. */
+extern void longjmp __P ((jmp_buf __env, int __val))
+ __attribute__ ((__noreturn__));
+#if defined __USE_BSD || defined __USE_XOPEN
+/* Same. Usually `_longjmp' is used with `_setjmp', which does not save
+ the signal mask. But it is how ENV was saved that determines whether
+ `longjmp' restores the mask; `_longjmp' is just an alias. */
+extern void _longjmp __P ((jmp_buf __env, int __val))
+ __attribute__ ((__noreturn__));
+#endif
+
+
+#ifdef __USE_POSIX
+/* Use the same type for `jmp_buf' and `sigjmp_buf'.
+ The `__mask_was_saved' flag determines whether
+ or not `longjmp' will restore the signal mask. */
+typedef jmp_buf sigjmp_buf;
+
+/* Store the calling environment in ENV, also saving the
+ signal mask if SAVEMASK is nonzero. Return 0. */
+# define sigsetjmp(env, savemask) __sigsetjmp ((env), (savemask))
+
+/* Jump to the environment saved in ENV, making the
+ sigsetjmp call there return VAL, or 1 if VAL is 0.
+ Restore the signal mask if that sigsetjmp call saved it.
+ This is just an alias `longjmp'. */
+extern void siglongjmp __P ((sigjmp_buf __env, int __val))
+ __attribute__ ((__noreturn__));
+#endif /* Use POSIX. */
+
+__END_DECLS
+
+#endif /* setjmp.h */
--- /dev/null
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Define the machine-dependent type `jmp_buf'. PowerPC version. */
+
+#ifndef _SETJMP_H
+#define _SETJMP_H 1
+
+typedef long int __jmp_buf[58];
+
+typedef struct __jmp_buf_tag
+{
+ __jmp_buf __jmpbuf;
+ int __mask_was_saved;
+ int __saved_mask;
+} jmp_buf[1];
+
+
+extern int __sigsetjmp (jmp_buf __env, int __savemask);
+#define setjmp(env) __sigsetjmp ((env), 0)
+
+extern void longjmp (jmp_buf __env, int __val);
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * include/stdlib.h
+ *
+ */
+#ifndef __STDLIB_H
+#define __STDLIB_H
+
+#include "stdarg.h"
+
+extern void malloc_init(void *bottom, unsigned long size);
+extern void malloc_dispose(void);
+
+extern void *malloc(unsigned int size);
+extern void *realloc(void *ptr, unsigned int size);
+extern void free (void *m);
+extern void mark (void **ptr);
+extern void release (void *ptr);
+
+extern int sprintf(char * buf, const char *fmt, ...);
+extern int vsprintf(char *buf, const char *fmt, va_list args);
+extern long simple_strtol(const char *cp,char **endp,unsigned int base);
+#define strtol(x,y,z) simple_strtol(x,y,z)
+
+#endif
--- /dev/null
+#ifndef _LINUX_STRING_H_
+#define _LINUX_STRING_H_
+
+#include "types.h"
+#include "stddef.h"
+
+extern char * ___strtok;
+extern char * strcpy(char *,const char *);
+extern char * strncpy(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);
+extern char * strrchr(const char *,int);
+extern char * strpbrk(const char *,const char *);
+extern char * strtok(char *,const char *);
+extern char * strstr(const char *,const char *);
+extern size_t strlen(const char *);
+extern size_t strspn(const char *,const char *);
+extern int strcmp(const char *,const char *);
+extern int strncmp(const char *,const char *,size_t);
+extern int strnicmp(const char *, const char *, size_t);
+extern void *strdup(char *str);
+
+extern void * memset(void *,int,size_t);
+extern void * memcpy(void *,const void *,size_t);
+extern void * memmove(void *,const void *,size_t);
+extern void * memscan(void *,int,size_t);
+extern int memcmp(const void *,const void *,size_t);
+
+static inline size_t strnlen(const char *s,size_t max)
+{
+ size_t sz = strlen(s);
+ return sz > max ? max : sz;
+}
+#endif /* _LINUX_STRING_H_ */
--- /dev/null
+#ifndef _REISERFS_SWAB_H_
+#define _REISERFS_SWAB_H_
+/* Stolen from linux/include/linux/byteorder/swab.h */
+#define swab16(x) \
+ ((__u16)( \
+ (((__u16)(x) & (__u16)0x00ffU) << 8) | \
+ (((__u16)(x) & (__u16)0xff00U) >> 8) ))
+#define swab32(x) \
+ ((__u32)( \
+ (((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
+ (((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
+ (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
+ (((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
+#define swab64(x) \
+ ((__u64)( \
+ (__u64)(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \
+ (__u64)(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \
+ (__u64)(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \
+ (__u64)(((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \
+ (__u64)(((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \
+ (__u64)(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
+ (__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
+ (__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) ))
+
+#endif /* _REISERFS_SWAB_H_ */
--- /dev/null
+#ifndef __TYPES_H
+#define __TYPES_H
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* bsd */
+typedef unsigned char u_char;
+typedef unsigned short u_short;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+
+/* sysv */
+typedef unsigned char unchar;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+typedef __u8 u_int8_t;
+typedef __s8 int8_t;
+typedef __u16 u_int16_t;
+typedef __s16 int16_t;
+typedef __u32 u_int32_t;
+typedef __s32 int32_t;
+
+typedef __u8 uint8_t;
+typedef __u16 uint16_t;
+typedef __u32 uint32_t;
+
+typedef __u64 uint64_t;
+typedef __u64 u_int64_t;
+typedef __s64 int64_t;
+
+typedef unsigned int ino_t;
+typedef __u64 loff_t;
+
+#endif
--- /dev/null
+#ifndef __VIDEO_H__
+#define __VIDEO_H__
+
+
+
+#endif
\ No newline at end of file
--- /dev/null
+#ifndef __YABOOT_H__
+#define __YABOOT_H__
+
+#include "file.h"
+
+struct boot_param_t {
+ struct boot_fspec_t kernel;
+ struct boot_fspec_t rd;
+ struct boot_fspec_t sysmap;
+ struct boot_fspec_t splash;
+
+ char* args;
+};
+
+extern int useconf;
+extern char bootdevice[];
+extern char *bootpath;
+extern int bootpartition;
+
+#endif
\ No newline at end of file
--- /dev/null
+#include "string.h"
+#include "ctype.h"
+
+unsigned char _ctype[] = {
+_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
+_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
+_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
+_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
+_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
+_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
+_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
+_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
+_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
+_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
+_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
+_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
+
+
+int strcasecmp(const char *s1, const char *s2)
+{
+ int c1, c2;
+
+ for (;;) {
+ c1 = *s1++;
+ if ('A' <= c1 && c1 <= 'Z')
+ c1 += 'a' - 'A';
+ c2 = *s2++;
+ if ('A' <= c2 && c2 <= 'Z')
+ c2 += 'a' - 'A';
+ if (c1 != c2 || c1 == 0)
+ return c1 - c2;
+ }
+}
+
--- /dev/null
+/* Dumb memory allocation routines
+
+ Copyright (C) 1997 Paul Mackerras
+ 1996 Maurizio Plaza
+ 1996 Jakub Jelinek
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "types.h"
+#include "stddef.h"
+
+/* Imported functions */
+extern void prom_printf (char *fmt, ...);
+
+static char *malloc_ptr = 0;
+static char *malloc_top = 0;
+static char *last_alloc = 0;
+
+void malloc_init(void *bottom, unsigned long size)
+{
+ malloc_ptr = bottom;
+ malloc_top = bottom + size;
+}
+
+void malloc_dispose(void)
+{
+ malloc_ptr = 0;
+ last_alloc = 0;
+}
+
+void *malloc (unsigned int size)
+{
+ char *caddr;
+
+ if (!malloc_ptr)
+ return NULL;
+ if ((malloc_ptr + size + sizeof(int)) > malloc_top) {
+ prom_printf("malloc failed\n");
+ return NULL;
+ }
+ *(int *)malloc_ptr = size;
+ caddr = malloc_ptr + sizeof(int);
+ malloc_ptr += size + sizeof(int);
+ last_alloc = caddr;
+ malloc_ptr = (char *) ((((unsigned int) malloc_ptr) + 3) & (~3));
+ return caddr;
+}
+
+void *realloc(void *ptr, unsigned int size)
+{
+ char *caddr, *oaddr = ptr;
+
+ if (!malloc_ptr)
+ return NULL;
+ if (oaddr == last_alloc) {
+ if (oaddr + size > malloc_top) {
+ prom_printf("realloc failed\n");
+ return NULL;
+ }
+ *(int *)(oaddr - sizeof(int)) = size;
+ malloc_ptr = oaddr + size;
+ return oaddr;
+ }
+ caddr = malloc(size);
+ if (caddr != 0 && oaddr != 0)
+ memcpy(caddr, oaddr, *(int *)(oaddr - sizeof(int)));
+ return caddr;
+}
+
+void free (void *m)
+{
+ if (!malloc_ptr)
+ return;
+ if (m == last_alloc)
+ malloc_ptr = (char *) last_alloc - sizeof(int);
+}
+
+void mark (void **ptr)
+{
+ if (!malloc_ptr)
+ return;
+ *ptr = (void *) malloc_ptr;
+}
+
+void release (void *ptr)
+{
+ if (!malloc_ptr)
+ return;
+ malloc_ptr = (char *) ptr;
+}
+
+void *strdup(char *str)
+{
+ char *p = malloc(strlen(str) + 1);
+
+ strcpy(p, str);
+ return p;
+}
--- /dev/null
+/* we got no time */
+long time()
+{
+ return 0;
+}
--- /dev/null
+/*
+ * String handling functions for PowerPC.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "asm/processor.h"
+#include "asm/ppc_asm.tmpl"
+
+ .globl strcpy
+strcpy:
+ addi r5,r3,-1
+ addi r4,r4,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ stbu r0,1(r5)
+ bne 1b
+ blr
+
+ .globl strncpy
+strncpy:
+ cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r6,r3,-1
+ addi r4,r4,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ stbu r0,1(r6)
+ bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
+ blr
+
+ .globl strcat
+strcat:
+ addi r5,r3,-1
+ addi r4,r4,-1
+1: lbzu r0,1(r5)
+ cmpwi 0,r0,0
+ bne 1b
+ addi r5,r5,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ stbu r0,1(r5)
+ bne 1b
+ blr
+
+ .globl strcmp
+strcmp:
+ addi r5,r3,-1
+ addi r4,r4,-1
+1: lbzu r3,1(r5)
+ cmpwi 1,r3,0
+ lbzu r0,1(r4)
+ subf. r3,r0,r3
+ beqlr 1
+ beq 1b
+ blr
+
+ .globl strncmp
+strncmp:
+ cmpwi 0,r5,0
+ addi r6,r3,-1
+ addi r4,r4,-1
+ beqlr
+ mtctr r5
+1: lbzu r3,1(r6)
+ cmpwi 1,r3,0
+ lbzu r0,1(r4)
+ subf. r3,r0,r3
+ beqlr 1
+ bdnzt 2,1b /* dec ctr, branch if ctr != 0 && cr0.eq */
+ blr
+
+ .globl strlen
+strlen:
+ addi r4,r3,-1
+1: lbzu r0,1(r4)
+ cmpwi 0,r0,0
+ bne 1b
+ subf r3,r3,r4
+ blr
+
+ .globl strchr
+strchr:
+ addi r3,r3,-1
+1: lbzu r0,1(r3)
+ cmpw 0,r0,r4
+ cmpwi 1,r0,0
+ beqlr
+ bne 1,1b
+ li r3,0
+ blr
+
+ .globl strrchr
+strrchr:
+ addi r5,r3,-1
+ li r3,0
+1: lbzu r0,1(r5)
+ cmpwi 0,r0,0
+ cmpw 1,r0,r4
+ beqlr
+ bne 1,1b
+ mr r3,r5
+ b 1b
+
+ .globl memset
+memset:
+ rlwimi r4,r4,8,16,23
+ rlwimi r4,r4,16,0,15
+ addi r6,r3,-4
+ cmplwi 0,r5,4
+ blt 7f
+ stwu r4,4(r6)
+ beqlr
+ andi. r0,r6,3
+ add r5,r0,r5
+ subf r6,r0,r6
+ rlwinm r0,r5,32-2,2,31
+ mtctr r0
+ bdz 6f
+1: stwu r4,4(r6)
+ bdnz 1b
+6: andi. r5,r5,3
+7: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r6,r6,3
+8: stbu r4,1(r6)
+ bdnz 8b
+ blr
+
+ .globl bcopy
+bcopy:
+ mr r6,r3
+ mr r3,r4
+ mr r4,r6
+ b memcpy
+
+ .globl __bzero
+__bzero:
+ mr r5, r4
+ li r4, 0
+ b memset
+
+ .globl memmove
+memmove:
+ cmplw 0,r3,r4
+ bgt backwards_memcpy
+ /* fall through */
+
+ .globl memcpy
+memcpy:
+ rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ addi r6,r3,-4
+ addi r4,r4,-4
+ beq 2f /* if less than 8 bytes to do */
+ andi. r0,r6,3 /* get dest word aligned */
+ mtctr r7
+ bne 5f
+1: lwz r7,4(r4)
+ lwzu r8,8(r4)
+ stw r7,4(r6)
+ stwu r8,8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,4(r4)
+ addi r5,r5,-4
+ stwu r0,4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+ addi r4,r4,3
+ addi r6,r6,3
+4: lbzu r0,1(r4)
+ stbu r0,1(r6)
+ bdnz 4b
+ blr
+5: subfic r0,r0,4
+ mtctr r0
+6: lbz r7,4(r4)
+ addi r4,r4,1
+ stb r7,4(r6)
+ addi r6,r6,1
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
+
+ .globl backwards_memcpy
+backwards_memcpy:
+ rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
+ add r6,r3,r5
+ add r4,r4,r5
+ beq 2f
+ andi. r0,r6,3
+ mtctr r7
+ bne 5f
+1: lwz r7,-4(r4)
+ lwzu r8,-8(r4)
+ stw r7,-4(r6)
+ stwu r8,-8(r6)
+ bdnz 1b
+ andi. r5,r5,7
+2: cmplwi 0,r5,4
+ blt 3f
+ lwzu r0,-4(r4)
+ subi r5,r5,4
+ stwu r0,-4(r6)
+3: cmpwi 0,r5,0
+ beqlr
+ mtctr r5
+4: lbzu r0,-1(r4)
+ stbu r0,-1(r6)
+ bdnz 4b
+ blr
+5: mtctr r0
+6: lbzu r7,-1(r4)
+ stbu r7,-1(r6)
+ bdnz 6b
+ subf r5,r0,r5
+ rlwinm. r7,r5,32-3,3,31
+ beq 2b
+ mtctr r7
+ b 1b
+
+ .globl memcmp
+memcmp:
+ cmpwi 0,r5,0
+ blelr
+ mtctr r5
+ addi r6,r3,-1
+ addi r4,r4,-1
+1: lbzu r3,1(r6)
+ lbzu r0,1(r4)
+ subf. r3,r0,r3
+ bdnzt 2,1b
+ blr
--- /dev/null
+/* Return the offset of one string within another.
+ Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/*
+ * My personal strstr() implementation that beats most other algorithms.
+ * Until someone tells me otherwise, I assume that this is the
+ * fastest implementation of strstr() in C.
+ * I deliberately chose not to comment it. You should have at least
+ * as much fun trying to understand it, as I had to write it :-).
+ *
+ * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
+
+#include <string.h>
+
+typedef unsigned chartype;
+
+#undef strstr
+
+char *
+strstr (phaystack, pneedle)
+ const char *phaystack;
+ const char *pneedle;
+{
+ register const unsigned char *haystack, *needle;
+ register chartype b, c;
+
+ haystack = (const unsigned char *) phaystack;
+ needle = (const unsigned char *) pneedle;
+
+ b = *needle;
+ if (b != '\0')
+ {
+ haystack--; /* possible ANSI violation */
+ do
+ {
+ c = *++haystack;
+ if (c == '\0')
+ goto ret0;
+ }
+ while (c != b);
+
+ c = *++needle;
+ if (c == '\0')
+ goto foundneedle;
+ ++needle;
+ goto jin;
+
+ for (;;)
+ {
+ register chartype a;
+ register const unsigned char *rhaystack, *rneedle;
+
+ do
+ {
+ a = *++haystack;
+ if (a == '\0')
+ goto ret0;
+ if (a == b)
+ break;
+ a = *++haystack;
+ if (a == '\0')
+ goto ret0;
+shloop: }
+ while (a != b);
+
+jin: a = *++haystack;
+ if (a == '\0')
+ goto ret0;
+
+ if (a != c)
+ goto shloop;
+
+ rhaystack = haystack-- + 1;
+ rneedle = needle;
+ a = *rneedle;
+
+ if (*rhaystack == a)
+ do
+ {
+ if (a == '\0')
+ goto foundneedle;
+ ++rhaystack;
+ a = *++needle;
+ if (*rhaystack != a)
+ break;
+ if (a == '\0')
+ goto foundneedle;
+ ++rhaystack;
+ a = *++needle;
+ }
+ while (*rhaystack == a);
+
+ needle = rneedle; /* took the register-poor approach */
+
+ if (a == '\0')
+ break;
+ }
+ }
+foundneedle:
+ return (char*) haystack;
+ret0:
+ return 0;
+}
--- /dev/null
+/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If
+ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+ Cambridge, MA 02139, USA. */
+
+/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
+ If BASE is 0 the base is determined by the presence of a leading
+ zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
+ If BASE is < 2 or > 36, it is reset to 10.
+ If ENDPTR is not NULL, a pointer to the character after the last
+ one converted is stored in *ENDPTR. */
+
+#include "ctype.h"
+
+int strtol (nptr, endptr, base)
+const char *nptr;
+char **endptr;
+int base;
+{
+ int negative;
+ register unsigned int cutoff;
+ register unsigned int cutlim;
+ register unsigned int i;
+ register const char *s;
+ register unsigned char c;
+ const char *save, *end;
+ int overflow;
+
+ if (base < 0 || base == 1 || base > 36)
+ base = 10;
+
+ save = s = nptr;
+
+ /* Skip white space. */
+ while (((unsigned char) *s) <= 32 && *s)
+ ++s;
+ if (*s == '\0')
+ goto noconv;
+
+ /* Check for a sign. */
+ if (*s == '-') {
+ negative = 1;
+ ++s;
+ } else if (*s == '+') {
+ negative = 0;
+ ++s;
+ } else
+ negative = 0;
+
+ if ((base == 16 && s[0] == '0' && (s[1] == 'X')) || (s[1] == 'x'))
+ s += 2;
+
+ /* If BASE is zero, figure it out ourselves. */
+ if (base == 0) {
+ if (*s == '0') {
+ if (s[1] == 'X' || s[1] == 'x') {
+ s += 2;
+ base = 16;
+ } else
+ base = 8;
+ } else
+ base = 10;
+ }
+
+ /* Save the pointer so we can check later if anything happened. */
+ save = s;
+
+ end = 0;
+
+ cutoff = 0x7FFFFFFF / (unsigned int) base;
+ cutlim = 0x7FFFFFFF % (unsigned int) base;
+
+ overflow = 0;
+ i = 0;
+ for (c = *s; c != '\0'; c = *++s) {
+ if (s == end)
+ break;
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c = c - 'A' + 10;
+ else if (c >= 'a' && c <= 'z')
+ c = c - 'a' + 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ /* Check for overflow. */
+ if (i > cutoff || (i == cutoff && c > cutlim))
+ overflow = 1;
+ else {
+ i *= (unsigned int) base;
+ i += c;
+ }
+ }
+
+ /* Check if anything actually happened. */
+ if (s == save)
+ goto noconv;
+
+ /* Store in ENDPTR the address of one character
+ past the last character we converted. */
+ if (endptr)
+ *endptr = (char *) s;
+
+ if (overflow)
+ return negative ? (int) 0x80000000 : (int) 0x7FFFFFFF;
+
+ /* Return the result of the appropriate sign. */
+ return (negative ? -i : i);
+
+ noconv:
+ /* We must handle a special case here: the base is 0 or 16 and the
+ first two characters and '0' and 'x', but the rest are no
+ hexadecimal digits. This is no error case. We return 0 and
+ ENDPTR points to the `x`. */
+ if (endptr) {
+ if (save - nptr >= 2 && tolower (save[-1]) == 'x' && save[-2] == '0')
+ *endptr = (char *) &save[-1];
+ else
+ /* There was no number to convert. */
+ *endptr = (char *) nptr;
+ }
+
+ return 0L;
+}
--- /dev/null
+/*
+ * linux/lib/vsprintf.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
+/*
+ * Wirzenius wrote this portably, Torvalds fucked it up :-)
+ */
+
+#include <stdarg.h>
+#include <types.h>
+#include <string.h>
+#include <ctype.h>
+
+
+/**
+ * simple_strtoul - convert a string to an unsigned long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
+{
+ unsigned long result = 0,value;
+
+ if (!base) {
+ base = 10;
+ if (*cp == '0') {
+ base = 8;
+ cp++;
+ if ((*cp == 'x') && isxdigit(cp[1])) {
+ cp++;
+ base = 16;
+ }
+ }
+ }
+ while (isxdigit(*cp) &&
+ (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
+ result = result*base + value;
+ cp++;
+ }
+ if (endp)
+ *endp = (char *)cp;
+ return result;
+}
+
+/**
+ * simple_strtol - convert a string to a signed long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+long simple_strtol(const char *cp,char **endp,unsigned int base)
+{
+ if(*cp=='-')
+ return -simple_strtoul(cp+1,endp,base);
+ return simple_strtoul(cp,endp,base);
+}
+
+/**
+ * simple_strtoull - convert a string to an unsigned long long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
+{
+ unsigned long long result = 0,value;
+
+ if (!base) {
+ base = 10;
+ if (*cp == '0') {
+ base = 8;
+ cp++;
+ if ((*cp == 'x') && isxdigit(cp[1])) {
+ cp++;
+ base = 16;
+ }
+ }
+ }
+ while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+ ? toupper(*cp) : *cp)-'A'+10) < base) {
+ result = result*base + value;
+ cp++;
+ }
+ if (endp)
+ *endp = (char *)cp;
+ return result;
+}
+
+/**
+ * simple_strtoll - convert a string to a signed long long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+long long simple_strtoll(const char *cp,char **endp,unsigned int base)
+{
+ if(*cp=='-')
+ return -simple_strtoull(cp+1,endp,base);
+ return simple_strtoull(cp,endp,base);
+}
+
+static int skip_atoi(const char **s)
+{
+ int i=0;
+
+ while (isdigit(**s))
+ i = i*10 + *((*s)++) - '0';
+ return i;
+}
+
+#define ZEROPAD 1 /* pad with zero */
+#define SIGN 2 /* unsigned/signed long */
+#define PLUS 4 /* show plus */
+#define SPACE 8 /* space if plus */
+#define LEFT 16 /* left justified */
+#define SPECIAL 32 /* 0x */
+#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
+
+static char * number(char * str, long long num, int base, int size, int precision, int type)
+{
+ char c,sign,tmp[66];
+ const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+ int i;
+
+ if (type & LARGE)
+ digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ if (type & LEFT)
+ type &= ~ZEROPAD;
+ if (base < 2 || base > 36)
+ return 0;
+ c = (type & ZEROPAD) ? '0' : ' ';
+ sign = 0;
+ if (type & SIGN) {
+ if (num < 0) {
+ sign = '-';
+ num = -num;
+ size--;
+ } else if (type & PLUS) {
+ sign = '+';
+ size--;
+ } else if (type & SPACE) {
+ sign = ' ';
+ size--;
+ }
+ }
+ if (type & SPECIAL) {
+ if (base == 16)
+ size -= 2;
+ else if (base == 8)
+ size--;
+ }
+ i = 0;
+ if (num == 0)
+ tmp[i++]='0';
+ else while (num != 0)
+ {
+ int t = ((long long) num) % (unsigned int) base;
+ tmp[i++] = digits[t];
+ num = ((long long) num) / (unsigned int) base;
+ }
+ if (i > precision)
+ precision = i;
+ size -= precision;
+ if (!(type&(ZEROPAD+LEFT)))
+ while(size-->0)
+ *str++ = ' ';
+ if (sign)
+ *str++ = sign;
+ if (type & SPECIAL) {
+ if (base==8)
+ *str++ = '0';
+ else if (base==16) {
+ *str++ = '0';
+ *str++ = digits[33];
+ }
+ }
+ if (!(type & LEFT))
+ while (size-- > 0)
+ *str++ = c;
+ while (i < precision--)
+ *str++ = '0';
+ while (i-- > 0)
+ *str++ = tmp[i];
+ while (size-- > 0)
+ *str++ = ' ';
+ return str;
+}
+
+/**
+ * vsprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
+ *
+ * Call this function if you are already dealing with a va_list.
+ * You probably want sprintf instead.
+ */
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+ int len;
+ unsigned long long num;
+ int i, base;
+ char * str;
+ const char *s;
+
+ int flags; /* flags to number() */
+
+ int field_width; /* width of output field */
+ int precision; /* min. # of digits for integers; max
+ number of chars for from string */
+ int qualifier; /* 'h', 'l', or 'L' for integer fields */
+ /* 'z' support added 23/7/1999 S.H. */
+ /* 'z' changed to 'Z' --davidm 1/25/99 */
+
+
+ for (str=buf ; *fmt ; ++fmt) {
+ if (*fmt != '%') {
+ *str++ = *fmt;
+ continue;
+ }
+
+ /* process flags */
+ flags = 0;
+ repeat:
+ ++fmt; /* this also skips first '%' */
+ switch (*fmt) {
+ case '-': flags |= LEFT; goto repeat;
+ case '+': flags |= PLUS; goto repeat;
+ case ' ': flags |= SPACE; goto repeat;
+ case '#': flags |= SPECIAL; goto repeat;
+ case '0': flags |= ZEROPAD; goto repeat;
+ }
+
+ /* get field width */
+ field_width = -1;
+ if (isdigit(*fmt))
+ field_width = skip_atoi(&fmt);
+ else if (*fmt == '*') {
+ ++fmt;
+ /* it's the next argument */
+ field_width = va_arg(args, int);
+ if (field_width < 0) {
+ field_width = -field_width;
+ flags |= LEFT;
+ }
+ }
+
+ /* get the precision */
+ precision = -1;
+ if (*fmt == '.') {
+ ++fmt;
+ if (isdigit(*fmt))
+ precision = skip_atoi(&fmt);
+ else if (*fmt == '*') {
+ ++fmt;
+ /* it's the next argument */
+ precision = va_arg(args, int);
+ }
+ if (precision < 0)
+ precision = 0;
+ }
+
+ /* get the conversion qualifier */
+ qualifier = -1;
+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
+ qualifier = *fmt;
+ ++fmt;
+ }
+
+ /* default base */
+ base = 10;
+
+ switch (*fmt) {
+ case 'c':
+ if (!(flags & LEFT))
+ while (--field_width > 0)
+ *str++ = ' ';
+ *str++ = (unsigned char) va_arg(args, int);
+ while (--field_width > 0)
+ *str++ = ' ';
+ continue;
+
+ case 's':
+ s = va_arg(args, char *);
+ if (!s)
+ s = "<NULL>";
+
+ len = strnlen(s, precision);
+
+ if (!(flags & LEFT))
+ while (len < field_width--)
+ *str++ = ' ';
+ for (i = 0; i < len; ++i)
+ *str++ = *s++;
+ while (len < field_width--)
+ *str++ = ' ';
+ continue;
+
+ case 'p':
+ if (field_width == -1) {
+ field_width = 2*sizeof(void *);
+ flags |= ZEROPAD;
+ }
+ str = number(str,
+ (unsigned long) va_arg(args, void *), 16,
+ field_width, precision, flags);
+ continue;
+
+
+ case 'n':
+ if (qualifier == 'l') {
+ long * ip = va_arg(args, long *);
+ *ip = (str - buf);
+ } else if (qualifier == 'Z') {
+ size_t * ip = va_arg(args, size_t *);
+ *ip = (str - buf);
+ } else {
+ int * ip = va_arg(args, int *);
+ *ip = (str - buf);
+ }
+ continue;
+
+ case '%':
+ *str++ = '%';
+ continue;
+
+ /* integer number formats - set up the flags and "break" */
+ case 'o':
+ base = 8;
+ break;
+
+ case 'X':
+ flags |= LARGE;
+ case 'x':
+ base = 16;
+ break;
+
+ case 'd':
+ case 'i':
+ flags |= SIGN;
+ case 'u':
+ break;
+
+ default:
+ *str++ = '%';
+ if (*fmt)
+ *str++ = *fmt;
+ else
+ --fmt;
+ continue;
+ }
+ if (qualifier == 'L') {
+ num = va_arg(args, unsigned long long);
+ if( flags & SIGN)
+ num = (signed long long) num;
+ } else if (qualifier == 'l') {
+ num = va_arg(args, unsigned long);
+ if (flags & SIGN)
+ num = (signed long) num;
+ } else if (qualifier == 'Z') {
+ num = va_arg(args, size_t);
+ } else if (qualifier == 'h') {
+ num = (unsigned short) va_arg(args, int);
+ if (flags & SIGN)
+ num = (signed short) num;
+ } else {
+ num = va_arg(args, unsigned int);
+ if (flags & SIGN)
+ num = (signed int) num;
+ }
+ str = number(str, num, base, field_width, precision, flags);
+ }
+ *str = '\0';
+ return str-buf;
+}
+
+/**
+ * sprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ */
+int sprintf(char * buf, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i=vsprintf(buf,fmt,args);
+ va_end(args);
+ return i;
+}
--- /dev/null
+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 Mon Aug 6 03:01:39 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 Mon Aug 6 02:43:23 2001
++++ man.deb/yaboot.conf.5 Mon Aug 6 03:01:39 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
+@@ -299,7 +299,7 @@
+ 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 set to a unix
++\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
+@@ -308,7 +308,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.
+@@ -318,7 +318,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.
+@@ -339,7 +339,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.
+@@ -587,8 +587,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 Mon Aug 6 03:01:39 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
--- /dev/null
+.\" Hey Emacs! This file is -*- nroff -*- source.
+.\" NewWorld section written by Ethan Benson OldWorld section taken
+.\" from bootstrap(8) from the quik package.
+.\"
+.TH BOOTSTRAP 8 "28 April 2001" "GNU/Linux PowerPC" "System Manager's Manual"
+.SH NAME
+.B bootstrap
+\- Disk boot process for PowerMac GNU/Linux
+.SH DESCRIPTION
+This man page describes the \fBbootstrap\fR process for both OldWorld and
+NewWorld PowerMacs. OldWorld PowerMacs all have a hardware MacOS ROM
+and the case is beige in color. NewWorld PowerMacs do not have a hardware
+MacOS ROM, and are in colored, translucent cases. All G3s in colored
+cases are NewWorld, as are all G4s and later. This man page is
+divided into three sections, OLDWORLD, NEWWORLD, and IBM. Please read the
+section appropriate to your hardware.
+.SH OLDWORLD
+The process of booting PowerMac/Linux from a disk starts with Open
+Firmware loading the boot block from the first bootable partition of
+the boot disk into memory. The user specifies which device is to be
+the boot disk by setting the \fBboot-device\fR environment variable to
+the Open Firmware name of the boot disk, or by giving it as an
+explicit argument to the Open Firmware \fBboot\fR command. OldWorld
+PowerMacs typically do not require \fBbootstrap\fR partitions like
+NewWorld PowerMacs do.
+
+Open Firmware then transfers control to the first-stage bootstrap
+(\fBfirst.b\fR), located at the beginning of the boot block. The boot
+block also contains the list of block numbers for the second-stage
+bootstrap. \fBFirst.b\fR reads these blocks into memory, thus loading
+the second-stage bootstrap.
+
+The task of the second-stage bootstrap (\fBsecond.b\fR) is to load the
+Linux kernel into memory and pass it any arguments given by the user.
+\fBSecond.b\fR can also be used for loading other programs, such as
+diagnostic programs or other operating systems, as long as they are
+present as an ELF binary in an ext2 filesystem.
+
+\fBSecond.b\fR gets two string values from Open Firmware,
+called \fIbootpath\fR and \fIbootargs\fR. \fIBootpath\fR is the Open
+Firmware name of the boot disk (i.e., the device that the first-stage
+bootstrap was loaded from). If Open Firmware auto-booted, or if the
+\fBboot\fR command was given without arguments, then \fIbootpath\fR
+and \fIbootargs\fR are set to the values of the \fBboot-device\fR and
+\fBboot-file\fR variables, respectively. If the \fBboot\fR command
+was given with arguments, the first argument becomes \fIbootpath\fR
+and any subsequent arguments are saved in \fIbootargs\fR.
+
+\fBSecond.b\fR uses the Open Firmware input and output devices for
+communicating with the user. By default, the modem port is used for
+both, but this can be changed by setting the Open Firmware
+\fBinput-device\fR and \fBoutput-device\fR variables.
+
+\fBSecond.b\fR starts by printing a message to indicate
+that it has started, and then reads the configuration file. By
+default, the configuration file is \fB/etc/quik.conf\fR(5) on the same
+partition as the boot block, but this can be overridden with \fBquik\fR(8).
+The configuration file must be on the same disk as the boot block.
+The format of the configuration file is described in \fBquik.conf\fR(5).
+
+Then \fBsecond.b\fR prints its \fBboot:\fR prompt and waits for the
+user to type a command line. Normally the configuration file
+specifies a timeout, and if the user does not type anything within
+that period of time, \fBsecond.b\fR proceeds using the \fIbootargs\fR
+value as the command line. If the timeout value is 0, \fBsecond.b\fR
+will always use the \fIbootargs\fR value, ignoring anything the user
+types. This can be useful when a modem is connected to the
+modem port.
+
+Having obtained a command line, \fBsecond.b\fR takes the first word
+(whitespace-separated) as the name of the program to load. Any
+remaining words on the line become arguments to be passed to the
+program when it is loaded. If the command line is empty,
+\fBsecond.b\fR uses the value of the \fBdefault\fR keyword in the
+configuration file, or failing that, the first program specified in
+the configuration file.
+
+The configuration file can specify several alternative programs to
+load (referred to as \fIimages\fR in the configuration file syntax),
+along with shorthand labels for them and extra arguments to be
+prepended to those specified by the user. The program name given in
+the command line can be either an explicit path name or a shorthand
+label. If it is a shorthand label, the configuration file gives the
+corresponding path name.
+
+Path names are of the form
+
+.RS
+.RI [ device\fB: ][ partno ]\fB/ filepath
+.RE
+
+where \fIdevice\fR is the Open Firmware name of the disk, \fIpartno\fR
+is the (decimal) number of the partition on that disk, and
+\fIfilepath\fR is the path to the file in the ext2 filesystem on that
+partition. The default for \fIdevice\fR is \fIbootpath\fR, and the
+default for \fIpartno\fR is the first bootable partition on
+\fIdevice\fR. Alternatively, the \fB/\fIfilepath\fR section can be
+replaced by a span of 512-byte blocks to load using the syntax
+.BI [ start - end ]
+where \fIstart\fR and \fIend\fR are decimal block numbers.
+
+\fBSecond.b\fR will attempt to open the file identified by the path
+name and load it into memory as an ELF binary. If the file cannot be
+found, or if it is not an ELF binary, \fBsecond.b\fR will print an
+error message and print its \fBboot:\fR prompt again. In this case
+there is no timeout and \fBsecond.b\fR does not use the \fIbootargs\fR
+value.
+
+Once \fBsecond.b\fR has loaded the program into memory, it transfers
+control to it, passing it the list of arguments.
+.SH NEWWORLD
+The process of booting so called NewWorld PowerMacs from disk starts
+with OpenFirmware first attempting to execute the file specified in
+the \fIboot-device\fR variable. Unlike older versions of OpenFirmware
+the NewWorld version will not attempt to read a boot sector. By
+default OpenFirmware attempts to load a file with HFS file type
+\*(lqtbxi\*(rq in the \*(lqblessed\*(rq directory from each partition
+of each disk OpenFirmware is aware of, the first partition/disk that
+is found to be bootable is booted immediately.
+
+.BR Ybin (8)
+configures a \fBbootstrap\fR partition to pass all of OpenFirmware's
+tests to determine if the partition is considered to be bootable or
+not. The boot script is given file type \*(lqtbxi\*(rq and the root
+directory is marked as \*(lqblessed\*(rq, the blessing is important
+because OpenFirmware will immediately consider a partition unbootable
+if no directory is marked as blessed (you can still manually execute a
+loader such as \fByaboot\fR(8) with OpenFirmware even without a blessed
+directory but it will not happen automatically).
+
+The MacOS System Folder is always marked as blessed, this is required
+for MacOS as well as OpenFirmware. The MacOS System Folder also
+contains its own boot loader which has the tbxi file type, this makes
+installing \fByaboot\fR(8) onto a MacOS partition is difficult. The only way
+to install \fByaboot\fR(8) on a MacOS boot partition is to modify
+OpenFirmware to boot the CHRP script directly. Given this it is
+highly recommended that you create a dedicated \fBbootstrap\fR
+partition for \fByaboot\fR(8).
+
+Since OpenFirmware boots the first partition it finds to be bootable
+it is important that the \fBbootstrap\fR partition be first on the
+disk before any MacOS partition, otherwise MacOS will be booted
+instead of a dual boot menu used with \fByaboot\fR(8).
+
+The \fBbootstrap\fR partition should also NOT be mountable by MacOS,
+the reason is MacOS will (almost always) closely inspect any blessed
+directories to make sure its real MacOS, if it is not satisfied that
+the contents are a real copy of MacOS it will unbless the directory,
+resulting in OpenFirmware no longer considering it bootable. The best
+way to protect against this is to create the \fBbootstrap\fR partition
+with the partition type \*(lqApple_Bootstrap\*(rq which OpenFirmware
+accepts as a valid HFS partition, but MacOS will ignore and refuse to
+mount. The \fBbootstrap\fR partition need not be any larger then
+800K. 800K is the minimum size of an HFS filesystem, and is much more
+then enough for this purpose. You need not, and should not keep
+kernels on this partition, \fByaboot\fR(8) will load them from your
+ext2fs root partition just fine, as well as from any HFS or HFS+
+partitions (\fByaboot\fR(8) uses OpenFirmware's HFS+ filesystem support).
+
+To create the \fBbootstrap\fR partition, use GNU \fBparted\fR(8) or
+\fBmac-fdisk\fR(8) to create a partiton of type \*(lqApple_Bootstrap\*(rq.
+This is documented better in \fBmac-fdisks-basics\fR
+(http://penguinppc.org/usr/ybin/doc/mac-fdisk-basics.shtml).
+
+The \fBbootstrap\fR need not and should not be mounted anywhere on
+your filesystem, especially not on top of /boot. \fBYaboot\fR(8) is
+able to load the kernels from the ext2fs root partition so that is
+where they should be kept.
+
+OpenFirmware maintains a hierarchy of all the hardware it is aware of.
+To access or specify a boot device you must use the OpenFirmware path.
+For example: the path to a SCSI hard disk partition might look like
+this: /pci@80000000/pci-bridge@d/ADPT,2930CU@2/@2:2 . The first part,
+pci@80000000, shows that the target device is accessed through the PCI
+bus. The next part is the PCI bridge, the next is the name of the SCSI host
+adapter installed (this name is provided by a BootROM on the card
+itself), and after that is the SCSI ID number. The colon delimits the
+device from partition specification, so the last 2 means the second
+partition of this device. After the partition number we can specify
+pathnames to files in two ways: lazy and absolute. The \*(lq,\*(rq delimits
+the OpenFirmware path from the location of the bootfile. \*(lq,\e\e:tbxi\*(rq
+specifies the file that has a HFS file type of
+\*(lqtbxi\*(rq in the blessed directory. If there is not blessed
+directory this will fail. The second is to specify a absolute
+pathname to an arbitrary file on the disk, example: 2:,yaboot would
+load the file named \*(lqyaboot\*(rq in the root directory of the
+filesystem. It is possible to load files in subdirectories but
+OpenFirmware does not always do this reliably, and any special
+characters such as an embedded space must be expressed like %20 (for a
+space) the directory separator used by OpenFirmware is the backslash
+\e. Example: 2:,\eboot\eyaboot. Determining the OpenFirmware path to
+a given device is unfortunately not a trivial task. If you are using
+the built in ATA hard disk you can use the alias \*(lqhd:\*(rq.
+
+\fBYbin\fR also includes a utility \fBofpath\fR(8) which can in most
+cases find the OpenFirmware device path from a unix device node (ie
+/dev/hda2).
+
+In addition to binary executables OpenFirmware can also execute a CHRP
+script. This is somewhat similar to a shell script. A CHRP script is
+useful to create simple boot menus, among other things. CHRP scripts
+are divided into sections in a way similar to HTML. Here is a basic
+example of a CHRP script used as a wrapper to \fByaboot\fR(8) (since
+OpenFirmware will only load a file with type \*(lqtbxi\*(rq if it is a
+CHRP script).
+.IP
+.nf
+<CHRP-BOOT>
+<COMPATIBLE>
+MacRISC
+</COMPATIBLE>
+<DESCRIPTION>
+GNU/Linux PowerPC bootloader
+</DESCRIPTION>
+<BOOT-SCRIPT>
+boot hd:,\\\\yaboot
+</BOOT-SCRIPT>
+</CHRP-BOOT>
+.fi
+.P
+The \fICOMPATIBLE\fR section defines what machines this script is
+compatible with, if the machine name encoded into the ROM does not
+match one of these entries OpenFirmware will print out a lot of
+incomprehensible junk and fail to load the script. The
+\fIDESCRIPTION\fR is ignored by OpenFirmware as far as I know. The
+\fIBOOT-SCRIPT\fR section is where arbitrary OpenFirmware Forth
+commands may go. They are executed the same way as you would enter
+them on the OpenFirmware command line. The entire script is wrapped
+with the \fICHRP-BOOT\fR tags so that such a script may be attached as
+a header to a binary file. Much more complicated and elaborate CHRP
+scripts are possible but that is beyond the scope of this document.
+
+\fBYbin\fR as of version 0.17 includes a more robust script that is
+automatically configured with the correct OpenFirmware paths based on
+/etc/yaboot.conf. This new script need not and should not be edited
+by the user.
+
+If you have G4 hardware then your OpenFirmware may already have a
+graphical boot selector built in. This selector can be accessed by
+holding down the option key when booting the machine. You should see
+a screen with buttons for each bootable partition. The current
+version (as of \fBybin\fR(8) 0.13) of ofboot includes a badge icon,
+the button with a penguin icon is your \fBbootstrap\fR partition. If
+you decide to use this built in selector you really do not need to use
+a CHRP script that provides a boot menu. Thanks to Nicholas Humfrey
+for creating the Badge icon.
+.SH IBM
+IBM hardware such as the RS/6000 require msdos style partition tables.
+In order to boot from the disk they require a type 0x41 PReP Boot
+\fBbootstrap\fR partition large enough to hold the bootloader
+(typically \fByaboot\fR(8)). The bootloader is copied onto the raw
+partition as there is no filesystem. This is done either with \fBdd\fR(1)
+or \fBmkofboot\fR(8).
+.SH BUGS
+OpenFirmware
+.SH AUTHORS
+\fBybin\fR, and the NEWWORLD, and IBM sections of this man page
+written by Ethan Benson <erbenson@alaska.net>
+.P
+The OLDWORLD section of this man page was taken from the \fBquik\fR(8)
+package, which was written by Paul Mackerras.
+.P
+.B yaboot
+was written by Benjamin Herrenschmidt <benh@kernel.crashing.org>.
+.SH SEE ALSO
+.BR dd (1),
+.BR mkofboot (8),
+.BR ofpath (8),
+.BR quik (8),
+.BR quik.conf (5),
+.BR yaboot (8),
+.BR ybin (8).
--- /dev/null
+.\" Hey Emacs! This file is -*- nroff -*- source.
+.\"
+.\" ybin (YaBoot INstaller) installs/updates the yaboot boot loader.
+.\" Copyright (C) 2000, 2001 Ethan Benson
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version 2
+.\" of the License, or (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+.\"
+.TH MKOFBOOT 8 "28 April 2001" "GNU/Linux PowerPC" "System Manager's Manual"
+.SH NAME
+.B mkofboot
+\- format bootstrap partition and install the yaboot boot loader
+.SH SYNOPSIS
+.B mkofboot
+.RB [ \ \-b | \-\-boot\ \fIdevice\ ]
+.RB [ \ \-o | \-\-ofboot\ \fIof-path\ ]
+.RB [ \ \-i | \-\-install\ \fIboot-file\ ]
+.RB [ \ \-C | \-\-config\ \fIconfig-file\ ]
+.RB [ \ \-m | \-\-magicboot\ \fIchrp-file\ ]
+.RB [ \ \-\-filesystem\ \fIhfs | \fImsdos | \fIraw\ ]
+.RB [ \ \-\-nobless\ ]
+.RB [ \ \-M | \-\-mount\ ]
+.RB [ \ \-\-hide\ ]
+.RB [ \ \-\-protect\ ]
+.RB [ \ \-\-nonvram\ ]
+.RB [ \ \-\-device\ \fIOF-dev\ ]
+.RB [ \ \-\-partition\ \fIroot-part-#\ ]
+.RB [ \ \-\-timeout\ \fItimeout\ ]
+.RB [ \ \-\-image\ \fIkernel\ ]
+.RB [ \ \-\-label\ \fIlabel\ ]
+.RB [ \ \-\-root\ \fIroot-dev\ ]
+.RB [ \ \-\-force\ ]
+.RB [ \ \-v | \-\-verbose\ ]
+.RB [ \ \-\-debug\ ]
+.RB [ \ \-h | \-\-help\ ]
+.RB [ \ \-V | \-\-version\ ]
+.SH DESCRIPTION
+This manual page explains
+.B mkofboot
+the initial installer for the
+.BR yaboot (8)
+boot loader enabling GNU/Linux to be booted by OpenFirmware.
+
+.B mkofboot
+does exactly the same thing as
+.BR ybin (8)
+except that it erases and creates a new filesystem (specified by
+\-\-filesystem) on the \fBbootstrap\fR(8) partition before copying the
+boot loader files to it. See the
+.BR ybin (8)
+man page for more details on the installation process.
+
+The \fBbootstrap\fR(8) need not and should not be mounted anywhere on
+your filesystem, especially not on top of /boot. \fBYaboot\fR(8) is able
+to load the kernels from the ext2fs root partition so that is where
+they should be kept. \fBMkofboot\fR will refuse to operate on the
+\fBbootstrap\fR(8) partition if it is mounted.
+.SH OPTIONS
+NOTE:
+.B mkofboot
+uses the exact same command line options as
+.BR ybin (8)
+so if you have already read the \fBybin\fR(8) man page you can skip this
+section.
+.TP
+.BR \-b ,\ \-\-boot\ \fIdevice
+Install the boot loader onto the specified device. This device should
+be that of your \fBbootstrap\fR(8) partition. For example, if your
+\fBbootstrap\fR partition is located on your first primary IDE drive in the
+second partition, your device would be: \fI/dev/hda2\fR.
+.TP
+.BR \-o ,\ \-\-ofboot\ \fIof-path
+The OpenFirmware device path to the \fBbootstrap\fR(8) partition. This
+is needed so the first stage \fIofboot\fR loader can be configured
+properly. It should include the OpenFirmware path including the
+partition number (but not any filename). Example: if your
+\fBbootstrap\fR(8) partition is /dev/hda2, the OF path will likely be
+hd:2. As of \fBmkofboot\fR 0.18 you no longer are required to specify
+this option. If left undefined \fBmkofboot\fR will attempt to figure
+out the OpenFirmware path automatically using the \fBofpath\fR(8)
+utility. You should only need to define this option if
+\fBofpath\fR(8) fails.
+.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).
+.TP
+.BR \-C ,\ \-\-config\ \fIconfig-file
+Use \fIconfig-file\fR as the \fBmkofboot\fR/\fByaboot\fR(8) configuration
+file instead of the default \fI/etc/yaboot.conf\fR.
+.TP
+.BR \-m ,\ \-\-magicboot\ \fIchrp-script
+Use \fIchrp-script\fR as the boot loader \*(lqwrapper\*(rq. This
+script is needed to either provide a boot menu for dual boot with
+MacOS or to load yaboot (due to an OpenFirmware bug).
+.TP
+.BR \-\-filesystem\ \fIhfs\fR|\fImsdos\fR|\fIraw\fR
+Set the filesystem type that \fBmkofboot\fR will create on the
+\fBbootstrap\fR(8). The \*(lqraw\*(rq filesystem type causes
+\fBmkofboot\fR to copy the bootloader (the value of \fIinstall=\fR
+directly to the \fBbootstrap\fR(8) partition without creating a
+filesystem. \*(lqraw\*(rq is required on IBM hardware. CAUTION: this
+will destroy any data or filesystem on the \fBbootstrap\fR(8)
+partition (value of \fIboot=\fR) if you specify something like
+\fIboot=/dev/sda\fR you will destroy the partition table and lose ALL
+data on the disk. The default is HFS.
+.TP
+.BR \-M ,\ \-\-mount
+Do not use the userspace
+.BR hfsutils (1)
+to modify the \fBbootstrap\fR(8), instead try and mount the filesystem
+directly. NOTE: Attributes cannot be set on the filesystem or the
+boot loader files using this method, your system will NOT be bootable
+without modifying OpenFirmware's \*(lqboot-device\*(rq variable to something
+like: \*(lqhd:2,ofboot\*(rq (no quotes).
+.TP
+.BR \-\-nobless
+Do not \*(lqbless\*(rq the root directory of the \fBbootstrap\fR(8)
+partition's filesystem. Only use this option if the \fBbootstrap\fR(8)
+partition is actually a MacOS boot partition. This option is ignored
+unless the filesystem is HFS, and is ignored when used with \-\-mount.
+.TP
+.BR \-\-hide
+.br
+Set the invisible bit on all the boot loader files once copied to the
+\fBbootstrap\fR(8) partition. This setting is useful if you must install
+the boot loader onto a MacOS boot partition and do not with to see the
+boot loader files cluttering up the MacOS root directory. This option
+is ignored unless the filesystem is HFS, and will not work
+with \-\-mount.
+.TP
+.BR \-\-protect
+Set the read-only bit on all boot loader files once copied to the
+\fBbootstrap\fR(8) partition. This setting is useful if you must install
+the bootloader onto a MacOS boot partition and want to discourage
+alterations/deletion of the boot loader. This option works for both
+HFS and MSDOS filesystems.
+.TP
+.BR \-\-nonvram
+Prevent \fBmkofboot\fR from setting the OpenFirmware boot-device
+variable with \fBnvsetenv\fR(8).
+.TP
+.BR \-\-device\ \fIopenfirmware-dev-path
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the OpenFirmware device of the disk the system will boot
+from. The default is \*(lqhd:\*(rq.
+.TP
+.BR \-\-partition\ \fIroot-partition-number
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the partition number of the root filesystem. Mac partition
+tables are considered a partition themselves, so the first real
+partition will be 2, usually the \fBbootstrap\fR(8) partition, followed
+by the root partition, number 3.
+.TP
+.BR \-\-timeout\ \fItimeout
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the timeout value in tenths of a second. The timeout is how
+long \fByaboot\fR(8) will wait before booting the default (first listed)
+image.
+.TP
+.BR \-\-image\ \fIkernel-image
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the path to the default kernel to be booted.
+.TP
+.BR \-\-label\ \fIlabel
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the label used to boot the above kernel image. The default
+is Linux.
+.TP
+.BR \-\-root\ \fIroot-device
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the Linux device of the root partition. This is passed to
+the kernel at boot time. The default is \fI/dev/hda3\fR.
+.TP
+.BR \-v ,\ \-\-verbose
+This option causes \fBmkofboot\fR to be more verbose as it proceeds.
+.TP
+.BR \-f ,\ \-\-force
+This option suppresses any confirmation questions.
+.TP
+.BR \-\-debug
+This option causes \fBmkofboot\fR to output some boring details useful
+only for debugging \fBmkofboot\fR itself.
+.TP
+.BR \-h ,\ \-\-help
+Print out usage information and exit.
+.TP
+.BR \-V ,\ \-\-version
+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
+/etc/yaboot.conf \- boot loader/mkofboot configuration file
+.fi
+.SH ENVIRONMENT
+.TP
+.B TMPDIR
+.br
+The temporary directory \fBmkofboot\fR will use.
+.SH SECURITY
+The \fByaboot.conf\fR(5) auto generation requires a temporary file, this
+file is created with
+.BR mktemp (1)
+it is important that your system use a secure
+.BR mktemp (1)
+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
+\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
+specified there.
+.SH BUGS
+.B Mkofboot
+should be able to take care of OpenFirmware variables as needed on IBM
+hardware.
+.SH AUTHORS
+.BR mkofboot (8)
+, and this man page written by Ethan Benson.
+.br
+.BR yaboot (8)
+was written by Benjamin Herrenschmidt.
+.SH REPORTING BUGS
+Report bugs to <erbenson@alaska.net>
+.br
+Report bugs in \fByaboot\fR(8) to <benh@kernel.crashing.org>
+.SH SEE ALSO
+.BR bootstrap (8),
+.BR hfsutils (1),
+.BR mkofboot (8),
+.BR mktemp (1),
+.BR mount (8),
+.BR nvsetenv (8),
+.BR ofpath (8),
+.BR yaboot (8),
+.BR yaboot.conf (5).
--- /dev/null
+.\" Hey Emacs! This file is -*- nroff -*- source.
+.\"
+.\" ofpath: determine OpenFirmware path from unix device node
+.\" Copyright (C) 2000, 2001 Ethan Benson
+.\"
+.\" Portions based on show_of_path.sh:
+.\"
+.\" Copyright (C) 2000 Olaf Hering <olh@suse.de>
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version 2
+.\" of the License, or (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+.\"
+.TH OFPATH 8 "27 May 2001" "GNU/Linux PowerPC" "System Manager's Manual"
+.SH NAME
+.B ofpath
+\- determine OpenFirmware path from unix device node.
+.SH SYNOPSIS
+.B ofpath
+.RB [ \ \-\-debug\ ]
+.RB [ \ \-h | \-\-help\ ]
+.RB [ \ \-V | \-\-version\ ]
+.IB FILE
+.SH DESCRIPTION
+This manual page explains
+.BR ofpath ,
+the utility used to find the OpenFirmware device path corresponding to
+a unix device node, such as \fI/dev/hda2\fR.
+
+.B ofpath
+will work on NewWorld PowerMacs only if yaboot is used as the
+bootloader. It will \fInot\fR work on NewWorld macs booted with BootX.
+
+.B ofpath
+will also work on some OldWorld PowerMacs. Unlike NewWorld, it will
+work on BootX-booted OldWorld machines. Note that OldWorld support is
+not well tested and may not give accurate results.
+
+\fBYbin\fR(8) uses this utility to automatically convert unix device
+nodes to OpenFirmware paths as needed.
+.SH OPTIONS
+.TP
+.BR \-\-debug
+This option causes \fBofpath\fR to output some boring details useful
+only for debugging \fBofpath\fR itself.
+.TP
+.BR \-h ,\ \-\-help
+Print out usage information and exit.
+.TP
+.BR \-V ,\ \-\-version
+Print out the version number and exit.
+
+.SH BUGS
+.B Ofpath
+may not accurately find all SCSI devices, and does not support all
+SCSI adapters/drivers.
+
+.B Ofpath
+also does not support all IDE devices.
+
+.B Ofpath
+does not support IBM hardware. Send a tarball of /proc/device-tree
+along with /proc/cpuinfo to <erbenson@alaska.net>
+.SH AUTHORS
+.B Ofpath
+is based on show_of_path.sh written by Olaf Hering, it was
+rewritten to work with /bin/ash and stripped down systems such as
+boot/rescue floppies by Ethan Benson. This man page was written by
+Ethan Benson.
+.SH REPORTING BUGS
+Report bugs to <erbenson@alaska.net>
+.SH SEE ALSO
+.BR bootstrap (8),
+.BR mkofboot (8),
+.BR yaboot (8),
+.BR yaboot.conf (5),
+.BR ybin (8).
--- /dev/null
+.\" Hey Emacs! This file is -*- nroff -*- source.
+.\"
+.TH YABOOT 8 "28 April 2001" "GNU/Linux PowerPC" "System Manager's Manual"
+.SH NAME
+.B yaboot
+\- PowerMac OpenFirmware boot loader
+.SH SYNOPSIS
+.B Yaboot
+is an OpenFirmware ELF executable that bootstraps the Linux kernel.
+.SH DESCRIPTION
+This manual page explains the \fByaboot\fR OpenFirmware boot loader.
+
+.B yaboot
+is \fInot\fR a Linux or MacOS executable file. Attempting to execute
+\fByaboot\fR from a Linux shell will only result in a Segmentation
+Fault. \fByaboot\fR is meant to be executed only by OpenFirmware.
+
+.B yaboot
+is executed from OpenFirmare in the following manner:
+.I boot hd:2,yaboot
+where \fIhd:\fR is the OpenFirmware path for the hard disk, and the
+\fI2\fR is the partition number \fByaboot\fR is located on. In this
+example, the hard disk path is actually an OpenFirmware alias which is
+present on all NewWorld powermacs. It usually points to the internal
+ATA hard disk. If you have a SCSI disk, then you might execute
+\fByaboot\fR with this command:
+.I boot /pci@80000000/pci-bridge@d/ADPT,2930CU@2/@1:2,yaboot
+This path will vary depending on what kind of SCSI host adapter you
+have. For a more detailed explanation of OpenFirmware's [disgusting]
+paths, see man \fBbootstrap\fR(8). On IBM hardware \fByaboot\fR is
+directly copied to the \fBbootstrap\fR(8) partition raw, without any
+filesystem. OpenFirmare will boot from a type 0x41 PReP Boot parition
+marked bootable, this must contain \fByaboot\fR. On IBM hardware the
+config file is read directly from the root filesystem. On PowerMac
+hardware it must be present on the \fBbootstrap\fR(8) partition but
+.BR ybin (8)
+will take care of that.
+
+Fortunately you do not normally have to execute \fByaboot\fR manually.
+If you have partitioned your disk with a \fBbootstrap\fR(8) partition
+and used \fBybin\fR(8) to install \fByaboot\fR then you will not have
+to execute \fByaboot\fR yourself. (If this does not work you can also
+set the \fIboot-device\fR variable in OpenFirmware to have it boot
+automatically, see man \fBbootstrap\fR(8).)
+
+Once \fByaboot\fR has been executed by OpenFirmware it will display a
+\fIboot:\fR prompt where you may enter a label for a kernel image
+defined in \fByaboot.conf\fR(5). If there is no kernel image defined
+in \fByaboot.conf\fR(5) you can still boot an arbitrary image by
+specifying its absolute OpenFirmware path, similar to the above
+commands for executing \fByaboot\fR itself. Simply omit the \fIboot\fR
+command and enter only the pathname. (See EXAMPLES below)
+
+When booting an image (either as a predefined label or absolute path)
+any arguments are passed to the image. For example:
+.I boot: linux root=/dev/hda3
+which would pass the argument \fIroot=/dev/hda3\fR to the kernel.
+
+.B yaboot
+should preferably be installed on a dedicated \fBbootstrap\fR(8)
+partition (type Apple_Bootstrap for PowerMacs, type 0x41 PReP Boot for
+IBM hardware). This allows the partition to be modified in such a way
+that OpenFirmare will load \fByaboot\fR or a boot menu automatically
+with a default OF configuration. If \fByaboot\fR cannot be installed
+on a \fBbootstrap\fR(8) partition it can be installed on the root of a
+MacOS boot partition instead. \fByaboot\fR however should not be
+installed in a subdirectory of the MacOS filesystem as this is less
+reliable and more difficult to execute from OpenFirmware. See the
+\fBybin\fR(8) man page for more details on installing \fByaboot\fR
+(\fBybin\fR(8) is a utility for installing \fByaboot\fR with minimal
+difficulty).
+
+The \fByaboot.conf\fR(5) file must be next to the yaboot executable on
+the \fBbootstrap\fR(8) partition. \fBybin\fR(8) will take care of this.
+
+OpenFirmware may be accessed by holding down the \fIcommand, option,
+o, f\fR keys immediately upon power-up.
+
+OpenFirmware's settings may be reset to default values by holding down
+the \fIcommand, option, p, r\fR keys while cold booting.
+
+If you have G4 hardware then your OpenFirmware may already have a
+graphical boot selector built in. This selector can be accessed by
+holding down the option key when booting the machine. You should see
+a screen with buttons for each bootable partition. The current
+version (included with \fBybin\fR(8) 0.13) of ofboot includes a
+badge icon, the button with a penguin icon is your \fBbootstrap\fR(8)
+partition. Thanks to Nicholas Humfrey for creating the Badge icon.
+
+The \fBbootstrap\fR(8) need not and
+.B should not
+be mounted anywhere on your filesystem, especially not on top of /boot. \fBYaboot\fR is able
+to load the kernels from the ext2fs root partition so that is where
+they should be kept.
+.SH EXAMPLES
+boot \fByaboot\fR from internal ATA disk, partition 2:
+
+.I boot hd:2,yaboot
+
+boot \fByaboot\fR from partition 2 of a disk with SCSI ID 2 attached to a
+Adaptec 2930 SCSI Host adapter (this is on a rev1 blue G3, it may vary
+on other models):
+
+.I boot /pci@80000000/pci-bridge@d/ADPT,2930CU@2/@2:2,yaboot
+
+boot a kernel image located on partition number 3 of internal ATA
+disk (from \fByaboot's\fR \fIboot:\fR prompt):
+
+.I hd:3,/boot/vmlinux
+
+boot a kernel image located on partition 3 of SCSI disk ID 2 on a
+Adaptec 2930 Host adapter (from \fByaboot's\fR \fIboot:\fR prompt):
+
+.I /pci@80000000/pci-bridge@d/ADPT,2930CU@2/@2:3,/vmlinux
+.SH FILES
+.nf
+/etc/yaboot.conf \- boot loader configuration file
+.fi
+.SH BUGS
+OpenFirmware
+.SH AUTHORS
+This man page was written by Ethan Benson <erbenson@alaska.net>.
+.P
+.B yaboot
+was written by Benjamin Herrenschmidt <benh@kernel.crashing.org>.
+.SH REPORTING BUGS
+Bugs in \fByaboot\fR should be reported to Benjamin Herrenschmidt
+<benh@kernel.crashing.org>.
+.SH SEE ALSO
+.BR bootstrap (8),
+.BR yaboot.conf (5),
+.BR ybin (8).
--- /dev/null
+.\" Copyright (c) 2001 Ethan Benson <erbenson@alaska.net>
+.\" Portions of this manual page from silo.conf documentation
+.\" Copyright (c) 1999 Jakub Jelinek <jakub@redhat.com>
+.\" Portions of this manual page from lilo.conf documentation
+.\" Copyright (c) 1992-1998 Werner Almesberger
+.\" This program is distributed according to the Gnu General Public License.
+.\" See the file COPYING in the ybin source distribution.
+.\"
+.TH YABOOT.CONF 5 "28 May 2001" "GNU/Linux PowerPC" "File Formats"
+.SH NAME
+.B yaboot.conf
+\- Configuration file format used by
+.BR yaboot (8)
+and
+.BR ybin (8).
+.SH SYNOPSIS
+.BI "/etc/yaboot.conf"
+.SH DESCRIPTION
+The \fByaboot.conf\fP file is a configuration file for \fByaboot\fP
+which is read during booting, and for \fBybin\fR(8) to generate a boot
+menu and to properly install \fByaboot\fP onto the \fBbootstrap\fP(8)
+partition.
+
+\fByaboot.conf\fP provides instructions for \fByaboot\fP. This
+includes which kernels to load and what options to pass to them.
+\fByaboot\fP reads and parses its configuration file found on the
+\fBbootstrap\fR(8) partition on PowerMacs, and directly from the root
+filesystem on IBM PowerPC hardware. On PowerMacs you must run the
+\fBybin\fR(8) command each time you modify \fB/etc/yaboot.conf\fR.
+
+\fByaboot\fP is able to boot kernels even without this configuration file or
+if this file is crippled or contains syntax errors, but the user has to
+enter full OpenFirmware names and full path of the images to load and all options
+required for them manually.
+.SH "FILE FORMAT"
+The file consists of comments and variable assignments.
+.TP
+Comments
+Start with a \fI#\fP character, and continue to
+the end of the line.
+.TP
+Flag variables
+Consist of a single keyword and are followed by whitespace
+or the end of the file.
+.TP
+String variables
+Consist of the variable name, optional whitespace, a
+\fI=\fP character, optional whitespace, the value and required
+newline. IMPORTANT: \fBybin\fR(8) specific options do not support
+embedded spaces. It is important that there be no trailing whitespace
+at the end of a line.
+.TP
+File names
+Some string variables are expecting file names. A file name format in \fByaboot\fP
+is:
+
+ [<devicename>][<part>]<absolute_pathname>
+
+ or
+
+ [<devicename>][<part>][\fB[\fP<m>\fB-\fP<n>\fB]\fP]
+
+The first form refers to a file or directory on some supported filesystem
+(currently \fIext2\fP, \fIhfs\fP, \fIhfs+\fP or \fIiso9660\fP), the latter
+refers to a range of 512B blocks on a device. For a device block range,
+either <devicename>, or <part>, or [<m>-<n>] must be given.
+
+Optional <devicename> is the OpenFirmware name of the device the file or range
+is located on. See below for its syntax. For OpenFirmware the device
+name must be immediately followed by the \fI:\fP character. The default is
+the boot device yaboot was booted from, or the value of \fIdevice=\fR
+in \fB/etc/yaboot.conf\fR.
+
+Optional <part> is the 1 based partition number on the device. First
+partition is 1 (e.g. on \fI/dev/sda\fP in Linux is this \fI/dev/sda1\fP).
+The default is the default partition (the value of the \fIpartition\fP
+variable in the config file). Note that on Apple partition tables the
+first partition is always the partition table itself (/dev/sda1 is the
+partition table).
+
+<absolute_pathname> must start with a \fI/\fP character and is the
+pathname from the root of the filesystem on that device (unless it is the
+root filesystem this is different to the pathname you will see in GNU/Linux).
+
+<m> is the first block number (in blocksize 512 bytes) of the range to
+be loaded and <n> is the last block number plus one.
+.TP
+Device name syntax is:
+
+ <fully_qualified_prom_device_name>[\fB:\fP<part_number>]
+
+where the fully qualified OpenFirmware device name starts with a
+\fI/\fP character for the root of the OpenFirmware device tree and
+contains all the nodes from the root in the tree up to the disk device
+node. If some node contains more than one child node with the same
+name and the path has to go through such node, a \fI@\fP character
+followed by hexadecimal address pair is desirable to resolve the
+ambiguity. Optional partition number is a number that follows the
+\fI:\fP character \fI1\fP (for first partition) \fI2\fP (for second,
+partition, etc). OpenFirmware device names might look like:
+
+ /pci@80000000/pci-bridge@d/ADPT,2930CU@2/@0:
+ /pci/@d/mac-io/ata-3@20000/disk@1:
+ /pci/@d/pci-ata@1/ata-4@0/disk@0:
+ /pci/@d/pci-ata@1/ata-4@0/disk@1:
+
+OpenFirmware device names if specified as part of the file name (see above)
+should be followed by the \fI:\fP character to separate the device name from
+the optional Linux partition number, as shown above. For more information on
+this topic, consult
+.BR bootstrap (8).
+
+OpenFirmware also has some predefined aliases which are used instead
+of the longer canonical device names. Standard aliases include:
+
+ hd: - The primary master IDE hard disk.
+ ultra1: - The primary slave IDE hard disk.
+ cd: - The secondary master device (usually CDROM).
+ zip: - The secondary slave device (usually zip drive).
+.PP
+Variable names are case sensitive, values of string variables are also
+case sensitive.
+
+Blanks and equal signs may only be part of a variable name or a value if
+they are escaped by a backslash or if the value is embedded in double
+quotes. An equal sign may not be the only character in a name or value.
+
+An escaped tab is converted to an escaped blank. An escaped newline is
+removed from the input stream. An escaped backslash (i.e. two
+backslashes) is converted to a backslash. Inside quoted strings, only
+double quotes, backslashes and newlines can be escaped.
+
+Example:
+
+ # Simple yaboot.conf
+ boot=/dev/hda2
+ device=hd:
+ partition=3
+ magicboot=/usr/local/lib/yaboot/ofboot
+ timeout=50
+ root=/dev/hda3
+ read-only
+ # End of global variables - begin image labels
+ image=/boot/vmlinux
+ label=linux
+ image=/boot/vmlinux.old
+ label=old
+
+This file contains options for two distinct programs: the
+\fBybin\fR(8) (and \fBmkofboot\fR(8)) \fBbootstrap\fR(8) installer, and the
+\fByaboot\fR(8) bootloader, each ignores the other's configuration
+options.
+
+The \fBybin\fR/\fBmkofboot\fR options are:
+.B boot=
+.B ofboot=
+.B install=
+.B magicboot=
+.B delay=
+.B bsd=
+.B macos=
+.B macosx=
+.B darwin=
+.B defaultos=
+.B usemount
+.B mntpoint=
+.B fstype=
+.B hfstype=
+.B nobless
+.B hide
+.B protect
+.B nonvram
+.B enablecdboot
+.B enablenetboot
+.B enableofboot
+.B brokenosx
+
+The remaining options belong to \fByaboot\fR(8).
+.SH "GLOBAL OPTIONS"
+\fB/etc/yaboot.conf\fP begins with a possibly empty global options section.
+This section contains all variable assignments up to the first \fIimage\fP
+setting.
+
+The following global options are recognized:
+.TP
+.BI "boot=" boot-device
+Specifies the \fBbootstrap\fR(8) partition \fBybin\fR(8) will install
+the boot loader on. This partition needs to have an HFS or MSDOS
+filesystem created on it (except on IBM hardware). \fBybin\fR(8) will
+not create a filesystem. If a filesystem is not present run
+\fBmkofboot\fR(8) instead of \fBybin\fR(8) for the first time. The
+\fBbootstrap\fR(8) partition must have a partition type of
+Apple_Bootstrap to prevent MacOS[X] from mounting it. If MacOS is able
+to mount the \fBbootstrap\fR(8) partition it will make it unbootable
+by removing the attributes \fBybin\fR(8) set to make the partition
+bootable by OpenFirmware. The \fBbootstrap\fR partition must not be
+mounted anywhere on your filesystem, \fBybin\fR(8) and
+\fBmkofboot\fR(8) will refuse to operate on it if it is mounted. On
+IBM hardware the \fBbootstrap\fR(8) should be a type 0x41 PReP Boot
+partition.
+.TP
+.BI "ofboot=" of-path
+This option defines the OpenFirmware device path to the
+\fBbootstrap\fR(8) partition. This is needed so the first stage
+\fIofboot.b\fR loader can be configured properly. It should include
+the OpenFirmware path including the partition number (but not a
+filename). Example: if your bootstrap partition is /dev/hda2 the OF
+path will likely be hd:2. As of \fBybin\fR(8) 0.18 you no longer are
+required to (and should not) specify this option. If left undefined
+\fBybin\fR(8) will attempt to figure out the OpenFirmware path
+automatically using the \fBofpath\fR(8) utility. You should only need
+to define this option if \fBofpath\fR(8) fails.
+.TP
+.BI "install=" boot-loader
+Specifies the path to the \fByaboot\fR(8) OpenFirmware executable
+file. This file is copied by \fBybin\fR(8) to the \fBbootstrap\fR(8)
+partition. The default if this is not specified is
+\fI/usr/local/lib/yaboot/yaboot\fR or \fI/usr/lib/yaboot/yaboot\fR.
+.TP
+.BI "magicboot=" magicboot-script
+Specifies the path to an OpenFirmware CHRP script that \fBybin\fR(8)
+will copy to the \fBbootstrap\fR(8) partition. Such a script contains
+Forth commands that can allow you to do interesting things such as
+creating a boot menu to choose between MacOS or GNU/Linux. Currently
+you must use a magicboot script do to a bug in OpenFirmware.
+Eventually a CHRP header could be added to the \fByaboot\fR(8)
+executable so this can be optional. When this option is defined the
+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
+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
+for most PowerMacs or they will fail to boot. You cannot use
+magicboot scripts with IBM hardware.
+.TP
+.BI "default=" name
+Uses the specified image as the default boot image. If `default' is omitted,
+the image appearing first in the configuration file is used.
+.TP
+.BI "defaultos=" linux|bsd|macos|macosx|darwin
+Defines the default OS for the first stage multiboot menu to load, by
+default this is linux, which really means \fByaboot\fR.
+Valid values are: linux, bsd, macos, macosx, and
+darwin. This is only relevant if you have \fIbsd=\fR, \fImacos=\fR,
+\fImacosx=\fR, or \fIdarwin=\fR options defined.
+.TP
+.BI "message=" message_filename
+Specifies a file containing a message that is displayed before the boot
+prompt. [CURRENTLY UNIMPLEMENTED]
+.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
+configuration file should be only readable by the superuser and the
+password should differ if possible from other passwords on the system.
+See
+.BR chmod (1)
+to set permissions on
+.BR yaboot.conf (5).
+Passwords currently do not affect the multiboot menu entries
+(\fImacos=\fR, \fImacosx=\fR, etc).
+.TP
+.BI "timeout=" tsecs
+Sets a timeout (in tenths of a second) for keyboard input. If no key is
+pressed for the specified time, the first image is automatically booted.
+.TP
+.BI "delay=" secs
+Sets a timeout (in seconds) for an OS choice in the first stage
+\fIofboot\fR loader. If no key is pressed for the specified time, the
+default OS defined by \fIdefaultos=\fR (or GNU/Linux) is automatically
+booted. If this is left unset, the value of \fItimeout=\fR (converted
+to seconds) will be used.
+.TP
+.BI "init-code=" string
+Specifies that \fByaboot\fR(8) should call OpenFirmware to
+execute the string given (a series of forth commands) before printing
+the boot prompt.
+.TP
+.BI "fgcolor=" string
+Specifies the foreground (text) color used by \fByaboot\fR(8) and the
+multiboot menu. Available colors are: black, blue, light-blue, green,
+light-green, cyan, light-cyan, red, light-red, purple, light-purple,
+brown, light-gray, dark-gray, yellow, and white. The default is white.
+.TP
+.BI "bgcolor=" string
+Specifies the background color used by \fByaboot\fR(8) and the
+mulitboot menu. Available colors are: black, blue, light-blue, green,
+light-green, cyan, light-cyan, red, light-red, purple, light-purple,
+brown, light-gray, dark-gray, yellow, and white. The default is
+black.
+.TP
+.BI "bsd=" of-path
+The OpenFirmware or Unix device path to a NetBSD or OpenBSD bootstrap
+partition, this partition must already have the BSD ofwboot.elf
+bootloader installed in the root directory.. 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 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
+.BI "macos=" of-path
+The OpenFirmware or Unix device path to a MacOS 8.* or 9.* boot
+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
+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
+.BI "macosx=" of-path
+The OpenFirmware or unix device path to a MacOS X boot 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 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
+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
+.B "brokenosx"
+This option causes the menu entry for MacOSX to execute
+\\System\\Library\\CoreServices\\BootX from the macosx=device instead
+of the usual \\\\:tbxi. This is necessary if OSX is installed onto an
+HFS+ filesystem instead of UFS. When OSX is installed on an HFS+
+filesystem MacOS will mount and debless the OSX partition. Add this
+option if the OSX menu entry breaks after booting MacOS. You should
+not use this option if OSX is installed on a UFS filesystem, for UFS
+installs you specify the OSX bootstrap partition which is protected
+against MacOS. This option requires \fImacosx=\fR to be set.
+.TP
+.BI "darwin=" of-path
+The OpenFirmware or unix device path to a Darwin boot 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 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
+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
+.B "enablecdboot"
+This option adds an entry to the multiboot menu to boot from the CDROM drive.
+.TP
+.B "enablenetboot"
+This option adds an entry to the multiboot menu to boot from the network.
+.TP
+.B "enableofboot"
+This option adds an entry to the multiboot menu to boot into an
+OpenFirmware prompt.
+.TP
+.B "usemount"
+This option causes \fBybin\fR to use the regular \fBmount\fR(8)
+utilities to access the filesystem on the \fBbootstrap\fR(8) partition
+instead of the userspace \fBhfsutils\fR(1). This is not recommended
+for HFS filesystems since it is not possible to set all the attributes
+required for automatic OpenFirmware booting. If you use this option
+you will have to modify OpenFirmware's boot-device variable to make
+your machine bootable (see man \fBbootstrap\fR(8)). Without this option
+you can normally reset OpenFirmware to its default configuration and
+your system will boot automatically into GNU/Linux. (See
+\fBbootstrap\fR(8) for details) This option is required for MSDOS
+filesystems.
+.TP
+.BI "mntpoint=" /path/to/directory
+Requires \fIusemount\fR this works exactly like usemount does except it
+does not mount the \fBbootstrap\fR(8) partition but rather installs the
+bootloader into the directory defined as the mountpoint. The pathname
+MUST be clean, ie no embedded spaces or metacharacters. The directory
+may not be more then one subdirectory deep from the root of the
+partition (not necessarily the unix /). You must not have a trailing
+/ either. This option is NOT recommended since it has the same
+limitations as usemount, your system will not be bootable by
+OpenFirmware, it will only be manually bootable or bootable if you
+change the boot-device variable to the direct pathname to the
+bootloader (which \fBybin\fR(8) will attempt to do). WARNING: This
+option is not secure if untrusted users can write to the value of
+\fImntpoint=\fR, and the filesystem supports links.
+.TP
+.BI "fstype=" hfs|msdos|raw
+Specifies what kind of filesystem is created on the \fBbootstrap\fR(8)
+partition by \fBmkofboot\fR(8). It must be either \fIhfs\fR or
+\fImsdos\fR or \fIraw\fR. For Apple PowerMacs HFS is the only
+workable option unless you have partitioned your disk with Intel
+partition tables. \fBYbin\fR(8) also uses this option to determine how
+to access the partition properly. The \fIraw\fR type causes
+\fBybin\fR(8) or \fBmkofboot\fR(8) to copy the bootloader (value of
+\fIinstall=\fR) to the \fBbootstrap\fR(8) partition without any
+filesystem. CAUTION: this will destroy any data or filesystem on the
+\fBbootstrap\fR(8) partition (value of \fIboot=\fR) if you specify
+something like \fIboot=/dev/sda\fR you will destroy the partition
+table and lose ALL data on the disk. The default if omitted, is hfs.
+.TP
+.BI "hfstype=" type-code
+Specifies the four character HFS type code that is given to the boot
+loader (or magicboot script). The default is \fItbxi\fR and should
+not be changed unless you really know what you are doing, OpenFirmware
+(on PowerMacs) looks for a file of this type to execute as a boot
+loader so if you change this your system will not boot automatically.
+This is only meant for users who must use a MacOS boot partition as
+the bootstrap partition, otherwise the conflict of two \fItbxi\fR
+files could potentially cause MacOS to fail to boot. This code is
+only given to the file intended for OpenFirmware to boot. This option
+is ignored on non-HFS filesystems.
+.TP
+.B "nobless"
+This prevents \fBybin\fR(8) from \*(lqblessing\*(rq the root directory of
+the \fBbootstrap\fR(8) partition. Blessing the root directory is required
+for OpenFirmware to boot correctly. This should only be used when a
+MacOS boot partition is being used as the \fBbootstrap\fR(8) in which case
+blessing the root directory would make MacOS unbootable. If you use
+this option you must manually configure OpenFirmware to boot
+\fByaboot\fR(8). (see \fBbootstrap\fR(8))
+.TP
+.B "hide"
+This causes \fBybin\fR(8) to set the HFS invisible bit on all the boot
+loader files. OpenFirmware ignores this bit, but MacOS will not show
+invisible files in the Finder. This is useful if the \fBbootstrap\fR(8)
+partition is MacOS mountable and you want to prevent annoying MacOS
+lusers from screwing up your GNU/Linux boot loader ;-). This option is
+ignored for non-HFS filesystems.
+.TP
+.B "protect"
+This causes \fBybin\fR(8) to set the HFS/MSDOS read-only bit on all the boot
+loader files. MacOS will not allow a read-only file to be modified or
+deleted (but does not prevent anyone from removing this bit) This is
+only useful if the \fBbootstrap\fR(8) partition is MacOS mountable and
+you want to discourage modification/deletion of the boot loader.
+.TP
+.B "nonvram"
+This option prevents \fBybin\fR(8) from setting the OpenFirmware
+boot-device variable with \fBnvsetenv\fR(8).
+.PP
+In addition to these global options, per-image options \fIappend\fP,
+\fIdevice\fP, \fIimage\fP, \fIinitrd-prompt\fP, \fIinitrd-size\fP,
+\fIinitrd\fP, \fIpartition\fP, \fIpause-after\fP, \fIpause-message\fP,
+\fIramdisk\fP, \fIread-only\fP, \fIread-write\fP, \fIroot\fP and
+\fIrestricted\fR can be specified in the global section. They are used
+as defaults if they aren't specified in the configuration sections of
+the respective kernel images and will be used also for the arbitrary
+images specified on the input line and not mentioned in the
+configuration file (unless overridden by input line options).
+.SH "PER-IMAGE SECTIONS"
+A per-image section starts with either a line
+
+ \fBimage=\fP\fIfilename\fP
+
+(for booting from files)
+From the \fIimage\fP line on until next \fIimage\fP line are variable
+assignments and flags for this image's section. The following options
+and flags are recognized:
+.TP
+.BI "label=" name
+The bootloader uses the main file name (without its path) of each image
+specification to identify that image. A different name can be used by
+setting the variable `label'.
+.TP
+.BI "alias=" name
+A second name for the same entry can be used by specifying an alias.
+.TP
+.BI "partition=" part_no
+Specifies the default partition number (a digit, hda1 is part_no 1) to
+be used if some filename does not specify a partition number
+explicitly. The kernel images should be located on the root
+filesystem, thus \fIpartition\fR should usually be set to the root
+partition number. For example if the root partition is /dev/hda3 (the
+third partition), then \fIpartition\fR should be set to
+\fIpartition=3\fR.
+.TP
+.BI "device=" device_name
+Specifies the default device name to be used if some filename does not
+specify a device name explicitly. This defaults to the device
+\fByaboot\fP has been booted from if you don't specify \fIdevice\fP in either
+the global section or per-image section of the config file.
+.TP
+.BI "append=" string
+Appends the options specified to the parameter line
+passed to the kernel. This is typically used to
+specify parameters of hardware that can't be
+entirely auto-detected or for which probing may be
+dangerous. Example:
+
+ append = "video=ofonly"
+.TP
+.BI "literal=" string
+Like `append', but removes all other options (e.g. setting of the root
+device). Because vital options can be removed unintentionally with
+`literal', this option cannot be set in the global options section.
+.TP
+.BI "ramdisk=" size
+This specifies the size of the optional RAM disk. A value of zero indicates
+that no RAM disk should be created. If this variable is omitted, the RAM
+disk size configured into the boot image is used.
+.TP
+.BI "read-only"
+This specifies that the root file system should be mounted read-only.
+Typically, the system startup procedure re-mounts the root file system
+read-write later (e.g. after fsck'ing it).
+.TP
+.BI "read-write"
+This specifies that the root file system should be mounted read-write.
+.TP
+.BI "root=" root-device
+This specifies the device that should be mounted as root.
+.TP
+.BI "initrd=" filename
+Specifies the file that will be loaded at boot time as the initial RAM disk.
+Example:
+
+ initrd=/images/initrd.img
+
+yaboot will not decompress the initial ramdisk, the Linux kernel will do that.
+If the initial ramdisk does not fit on one media (usually floppy), you can
+split it into several pieces and separate the filenames in the list by
+\fI|\fP characters. In this case, you have to provide a non-zero
+\fIinitrd-size\fP and, if the images reside on different medias,
+\fIinitrd-prompt\fP as well.
+Example (on the first floppy is initrd1.img, on the second initrd2.img
+always in the root directory and the sum of both image sizes is 1700000
+bytes):
+
+ initrd=/initrd1.img|/initrd2.img
+ initrd-size=1700000
+ initrd-prompt
+.TP
+.BI "initrd-size=" size
+When more than one initial ramdisk part is specified in the \fIinitrd\fP
+setting, this option is required to be the sum of sizes of all the images
+mentioned on that line, in bytes. It is required so that yaboot can reserve
+space for the image, even though size of some parts has not been determined
+yet.
+.TP
+.BI "initrd-prompt"
+If more than one initial ramdisk part is specified, wait for user pressing a
+key between loading the different images, so that the user can exchange
+media. This flag is needed if some initrd parts reside on the same device,
+but different removable media. On the other side, if you e.g. load one part
+from a floppy and the second part from a hard disk, such option is not
+needed (the question is who'd write something like that into yaboot.conf).
+.TP
+.BI "pause-after"
+If this flag is specified, yaboot will stop after loading the kernel (and
+initial ramdisks if specified) and ask the user to press a key before
+continuing.
+.TP
+.BI "pause-message=" string
+If \fIpause-after\fP is specified, this variable specifies the string to
+print to the user when asking him to press a key. The default is:
+
+ Press ENTER to continue.
+.TP
+.BI "sysmap=" filename
+Specifies the path for the System.map file that goes with the kernel
+image (\fIimage=\fR). This is for 2.4 kernels with a kernel debugger only.
+.TP
+.BI "single-key"
+Enables booting the image by hitting a single key when the cursor is at the
+first character in the input line, without the need to press <ENTER>
+afterwards. \fIsingle-key\fP requires that either the image's label or its
+alias (or both) is a single character. If you need to specify parameters for
+such an image, or if you want to boot some other image which happens to
+start with the same letter, then you need to start the input line with at
+least one space which will be removed before processing but will disable
+this single-key feature.
+.TP
+.BI "restricted"
+Restricted limits the ability to customize command line arguments.
+\fIrestricted\fR has no effect if \fIpassword=\fR is not specified.
+A password is only required to boot the image specified in
+\fB/etc/yaboot.conf\fP if parameters are specified on the command line
+or if the user enters an image that is not specified in the configuration
+file at all (arbitrary file load). For an image not including
+the \fIrestricted\fR keyword (unless \fIrestricted\fR is in the global
+section), the password will be required. If \fIrestricted\fR
+is in the global section, all boot labels act as above (duh:).
+.SH EXAMPLES
+Here is an example \fIyaboot.conf\fR file:
+.IP
+.nf
+boot=/dev/hda2
+device=hd:
+root=/dev/hda3
+partition=3
+timeout=20
+install=/usr/local/lib/yaboot/yaboot
+magicboot=/usr/local/lib/yaboot/ofboot
+fgcolor=black
+bgcolor=green
+default=Linux
+defaultos=linux
+password=secret
+
+image=/boot/vmlinux
+ label=Linux
+ read-only
+ restricted
+
+image=/boot/vmlinux.old
+ label=linux.old
+ read-only
+
+macos=hd:9
+macosx=/dev/hda10
+.fi
+.SH NOTES
+The format defined in this man page will not work with versions of
+\fByaboot\fR(8) older then 0.6. The color options only work with
+yaboot 1.0 and later.
+.SH BUGS
+Some
+.B yaboot
+options may not be implemented fully.
+.SH AUTHORS
+This man page was derived from \fBsilo.conf\fR(5) written by Jakub
+Jelinek and the SparcLinux team, and modified for
+\fByaboot\fR(8)/\fBybin\fR(8) by Ethan Benson.
+.P
+\fByaboot\fR(8) was written by Benjamin Herrenschmidt <benh@kernel.crashing.org>.
+.P
+\fBybin\fR(8) was written by Ethan Benson <erbenson@alaska.net>.
+.SH SEE ALSO
+.BR bootstrap (8),
+.BR chmod (1),
+.BR hfsutils (1),
+.BR mkofboot (8),
+.BR mount (8),
+.BR nvsetenv (8),
+.BR ofpath (8),
+.BR yaboot (8),
+.BR ybin (8).
--- /dev/null
+.\" Hey Emacs! This file is -*- nroff -*- source.
+.\"
+.\" yabootconfig generates a simple /etc/yaboot.conf
+.\" Copyright (C) 2001 Ethan Benson
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version 2
+.\" of the License, or (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+.\"
+.TH YABOOTCONFIG 8 "22 June 2001" "GNU/Linux PowerPC" "System Manager's Manual"
+.SH NAME
+.B yabootconfig
+\- generates a simple /etc/yaboot.conf
+.SH SYNOPSIS
+.B yabootconfig
+.RB [ \ \-t | \-\-chroot\ \\fIdirectory\ ]
+.RB [ \ \-b | \-\-boot\ \fIdevice\ ]
+.RB [ \ \-r | \-\-root\ \fIdevice\ ]
+.RB [ \ \-q | \-\-quiet\ ]
+.RB [ \ \-\-noinstall\ ]
+.RB [ \ \-h | \-\-help\ ]
+.RB [ \ \-V | \-\-version\ ]
+.SH DESCRIPTION
+This manual page explains
+.B yabootconfig
+the configurator for the
+.BR yaboot (8)
+boot loader enabling GNU/Linux to be booted by OpenFirmware.
+Specifically it inspects the running system, generates a working
+.BR /etc/yaboot.conf (5)
+and then runs \fBmkofboot\fR(8) to make the system bootable.
+
+.B yabootconfig
+requires an 800K bootstrap partition on the same disk as the root
+partition. It must be type \*(lqApple_Bootstrap\*(rq for PowerMacs,
+and type \*(lq0x41 PPC PReP Boot\*(rq for IBM CHRP hardware.
+
+The \fBbootstrap\fR(8) must not be mounted anywhere on your
+filesystem, especially not on top of /boot. \fBYaboot\fR is able to
+load the kernels from the ext2fs root partition so that is where they
+should be kept. \fBmkofboot\fR will refuse to operate on the
+\fBbootstrap\fR(8) partition if it is mounted.
+
+.B yabootconfig
+requires \fBofpath\fR(8) in order to get the OpenFirmware device name
+for the root disk on PowerMacs.
+.SH OPTIONS
+.TP
+.BR \-t.,\ \-\-chroot\ \fIdirectory
+Cause \fByabootconfig\fR to work as if \fIdirectory\fR is the /
+directory. This is useful when booting from a rescue floppy or CDROM
+in which case you mount your true root filesystem on /target or /mnt.
+\fByabootconfig\fR will generate \fI<chroot>/etc/yaboot.conf\fR and
+pass the \*(lq-C <chroot>/etc/yaboot.conf\*(rq arguments to \fBmkofboot\fR(8).
+Example: yabootconfig --chroot /target
+.TP
+.BR \-r ,\ \-\-root\ \fIdevice
+Normally \fByabootconfig\fR will automatically determine the root
+partition by inspecting \fI<chroot>/etc/fstab\fR(5). This option
+forces it to use \fIdevice\fR instead of auto-detecting it. This
+option is only intended to be used by distribution installers which
+should already know with absolute certainty what the root partition
+device is.
+.TP
+.BR \-b ,\ \-\-boot\ \fIdevice
+Normally \fByabootconfig\fR will automatically find your
+\fBbootstrap\fR partition, this option forces it to use \fIdevice\fR
+instead of auto-detecting it. This option is only intended to be used
+by distribution installers which should already know with absolute
+certainty what the \fBbootstrap\fR partition device is. The
+\fBbootstrap\fR partition is where \fBmkofboot\fR(8) will install the
+bootloader onto, this device should be that of your \fBbootstrap\fR(8)
+partition. For example, if your \fBbootstrap\fR partition is located
+on your first primary IDE drive in the second partition, your device
+would be: \fI/dev/hda2\fR. IMPORTANT: The \fBbootstrap\fR partition
+WILL BE ERASED when \fByabootconfig\fR runs \fBmkofboot\fR(8).
+.TP
+.BR \-\-kernel\-args
+This option allows you to specify additional kernel arguments which
+will be placed in an \fIappend=\fR configuration variable in
+\fI/etc/yaboot.conf\fR(5). You must quote the arguments you supply to this
+option. Example: --kernel-args "video=ofonly"
+.TP
+.BR \-q ,\ \-\-quiet
+Normally \fByabootconfig\fR will ask permission and explain what it is
+about to do before proceeding, this option prevents \fByabootconfig\fR
+from asking any questions or displaying any informational messages
+except errors. This option also prevents \fByabootconfig\fR from
+interactively asking the user to locate a kernel image if it fails to
+find one in the standard locations. This option is only intended to
+be used by distribution installers which may run \fByabootconfig\fR in
+the background in order to make the disk bootable after OS installation.
+.TP
+.BR \-\-noinstall
+Normally \fByabootconfig\fR will automatically run \fBmkofboot\fR(8)
+after it successfully generates a valid
+\fI<chroot>/etc/yaboot.conf\fR. This option causes \fByabootconfig\fR
+to only generate the config file without installing the \fBbootstrap\fR.
+.TP
+.BR \-h ,\ \-\-help
+Print out usage information and exit.
+.TP
+.BR \-V ,\ \-\-version
+Print out the version number and exit.
+.SH FILES
+.nf
+/etc/fstab \- static information about the filesystems
+.br
+/etc/yaboot.conf \- bootloader/ybin configuration file
+.fi
+.SH AUTHORS
+.B yabootconfig
+and this man page was written by Ethan Benson.
+.br
+.B yaboot
+was written by Benjamin Herrenschmidt.
+.SH REPORTING BUGS
+Report bugs to <erbenson@alaska.net>
+.br
+Report bugs in \fByaboot\fR(8) to <benh@kernel.crashing.org>
+.SH SEE ALSO
+.BR bootstrap (8),
+.BR fstab (5),
+.BR mkofboot (8),
+.BR ofpath (8),
+.BR yaboot (8),
+.BR yaboot.conf (5),
--- /dev/null
+.\" Hey Emacs! This file is -*- nroff -*- source.
+.\"
+.\" ybin (YaBoot INstaller) installs/updates the yaboot boot loader.
+.\" Copyright (C) 2000, 2001 Ethan Benson
+.\"
+.\" This program is free software; you can redistribute it and/or
+.\" modify it under the terms of the GNU General Public License
+.\" as published by the Free Software Foundation; either version 2
+.\" of the License, or (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+.\"
+.TH YBIN 8 "27 April 2001" "GNU/Linux PowerPC" "System Manager's Manual"
+.SH NAME
+.B ybin
+\- install the yaboot boot loader to a bootstrap partition.
+.SH SYNOPSIS
+.B ybin
+.RB [ \ \-b | \-\-boot\ \fIdevice\ ]
+.RB [ \ \-o | \-\-ofboot\ \fIof-path\ ]
+.RB [ \ \-i | \-\-install\ \fIboot-file\ ]
+.RB [ \ \-C | \-\-config\ \fIconfig-file\ ]
+.RB [ \ \-m | \-\-magicboot\ \fIchrp-file\ ]
+.RB [ \ \-\-filesystem\ \fIhfs | \fImsdos | \fIraw\ ]
+.RB [ \ \-\-nobless\ ]
+.RB [ \ \-M | \-\-mount\ ]
+.RB [ \ \-\-hide\ ]
+.RB [ \ \-\-protect\ ]
+.RB [ \ \-\-nonvram\ ]
+.RB [ \ \-\-device\ \fIOF-dev\ ]
+.RB [ \ \-\-partition\ \fIroot-part-#\ ]
+.RB [ \ \-\-timeout\ \fItimeout\ ]
+.RB [ \ \-\-image\ \fIkernel\ ]
+.RB [ \ \-\-label\ \fIlabel\ ]
+.RB [ \ \-\-root\ \fIroot-dev\ ]
+.RB [ \ \-\-force\ ]
+.RB [ \ \-v | \-\-verbose\ ]
+.RB [ \ \-\-debug\ ]
+.RB [ \ \-h | \-\-help\ ]
+.RB [ \ \-V | \-\-version\ ]
+.SH DESCRIPTION
+This manual page explains
+.B ybin
+the installer for the
+.BR yaboot (8)
+boot loader enabling GNU/Linux to be booted by OpenFirmware.
+Specifically it copies the
+.B yaboot
+binary and
+.BR yaboot.conf (5)
+and usually a \*(lqmagicboot\*(rq script to a
+.BR bootstrap (8)
+partition.
+
+.B Ybin
+will set attributes on the boot loader files and to the
+.BR bootstrap (8)
+partition itself to allow OpenFirmware to recognise it as bootable,
+[usually] without requiring alterations to OpenFirmware's configuration.
+
+.B Ybin
+will also set the OpenFirmware boot-device variable to the device path
+of the \fBbootstrap\fR(8) partition using \fBnvsetenv\fR(8) when a
+NewWorld compatible version of \fBnvsetenv\fR(8) is available.
+
+.B Ybin
+requires that the
+.BR bootstrap (8)
+partition have an HFS or MSDOS filesystem already on it. For IBM
+hardware there is no filesystem on the \fBbootstrap\fR(8) partition,
+in this case use fstype=raw. When using the raw filesystem type
+\fBybin\fR requires that an ELF binary have already been installed on
+the \fBbootstrap\fR(8) partition. Use the companion
+.BR mkofboot (8)
+utility to install the boot loader onto a new
+.BR bootstrap (8)
+partition.
+
+The \fBbootstrap\fR(8) need not and should not be mounted anywhere on
+your filesystem, especially not on top of /boot. \fBYaboot\fR is able
+to load the kernels from the ext2fs root partition so that is where
+they should be kept. \fBYbin\fR will refuse to operate on the
+\fBbootstrap\fR(8) partition if it is mounted.
+.SH OPTIONS
+.TP
+.BR \-b ,\ \-\-boot\ \fIdevice
+Install the boot loader onto the specified device, this device should
+be that of your \fBbootstrap\fR(8) partition. For example, if your
+\fBbootstrap\fR partition is located on your first primary IDE drive in the
+second partition, your device would be: \fI/dev/hda2\fR.
+.TP
+.BR \-o ,\ \-\-ofboot\ \fIof-path
+The OpenFirmware device path to the \fBbootstrap\fR(8) partition. This
+is needed so the first stage \fIofboot\fR loader can be configured
+properly. It should include the OpenFirmware path including the
+partition number (but not any filename). Example: if your
+\fBbootstrap\fR(8) partition is /dev/hda2 the OF path will likely be
+hd:2. As of \fBybin\fR 0.18 you no longer are required to specify this
+option, if left undefined ybin will attempt to figure out the
+OpenFirmware path automatically using the \fBofpath\fR(8) utility.
+You should only need to define this option if \fBofpath\fR(8) fails.
+.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.
+.TP
+.BR \-C ,\ \-\-config\ \fIconfig-file
+Use \fIconfig-file\fR as the \fBybin\fR/\fByaboot\fR(8) configuration
+file instead of the default \fI/etc/yaboot.conf\fR.
+.TP
+.BR \-m ,\ \-\-magicboot\ \fIchrp-script
+Use \fIchrp-script\fR as the boot loader \*(lqwrapper\*(rq. This
+script is needed to either provide a boot menu for dual boot with
+MacOS or to load yaboot (due to an OpenFirmware bug).
+.TP
+.BR \-\-filesystem\ \fIhfs\fR|\fImsdos\fR|\fIraw
+Set the filesystem type that \fBybin\fR expects to find on the
+\fBbootstrap\fR(8). The \*(lqraw\*(rq filesystem type causes \fBybin\fR
+to copy the bootloader (the value of \fIinstall=\fR directly to the
+\fBbootstrap\fR(8) partition without creating a filesystem.
+\*(lqraw\*(rq is required on IBM hardware. CAUTION: this will destroy any data or
+filesystem on the bootstrap partition (value of \fIboot=\fR) if you
+specify something like \fIboot=/dev/sda\fR you will destroy the
+partition table and lose ALL data on the disk. The default is HFS.
+.TP
+.BR \-M ,\ \-\-mount
+Do not use the userspace
+.BR hfsutils (1)
+to modify the \fBbootstrap\fR(8), instead try and mount the filesystem
+directly. NOTE: Attributes cannot be set on the filesystem or the
+boot loader files using this method, your system will NOT be bootable
+without modifying OpenFirmware's \*(lqboot-device\*(rq variable to
+something like: \*(lqhd:2,ofboot\*(rq (no quotes).
+.TP
+.BR \-\-nobless
+Do not \*(lqbless\*(rq the root directory of the \fBbootstrap\fR(8)
+partition's filesystem. Only use this option if the \fBbootstrap\fR(8)
+partition is actually a MacOS boot partition. This option is ignored
+unless the filesystem is HFS, and is ignored when used with \-\-mount.
+.TP
+.BR \-\-hide
+.br
+Set the invisible bit on all the boot loader files once copied to the
+\fBbootstrap\fR(8) partition. This setting is useful if you must install
+the boot loader onto a MacOS boot partition and do not with to see the
+boot loader files cluttering up the MacOS root directory. This option
+is ignored unless the filesystem is HFS, and will not work with
+\-\-mount.
+.TP
+.BR \-\-protect
+Set the read-only bit on all boot loader files once copied to the
+\fBbootstrap\fR(8) partition. This setting is useful if you must install
+the bootloader onto a MacOS boot partition and want to discourage
+alterations/deletion of the boot loader. This option works for both
+HFS and MSDOS filesystems.
+.TP
+.BR \-\-nonvram
+Prevent \fBybin\fR from setting the OpenFirmware boot-device
+variable with \fBnvsetenv\fR(8).
+.TP
+.BR \-\-device\ \fIopenfirmware-dev-path
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the OpenFirmware device of the disk the system will boot
+from. The default is \*(lqhd:\*(rq.
+.TP
+.BR \-\-partition\ \fIroot-partition-number
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the partition number of the root filesystem. Mac partition
+tables are considered a partition themselves, so the first real
+partition will be 2, usually the \fBbootstrap\fR(8) partition, followed
+by the root partition, number 3.
+.TP
+.BR \-\-timeout\ \fItimeout
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the timeout value in tenths of a second. The timeout is how
+long \fByaboot\fR(8) will wait before booting the default (first listed)
+image.
+.TP
+.BR \-\-image\ \fIkernel-image
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the path to the default kernel to be booted.
+.TP
+.BR \-\-label\ \fIlabel
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the label used to boot the above kernel image. The default
+is Linux.
+.TP
+.BR \-\-root\ \fIroot-device
+This option is used for auto-generation of a \fByaboot.conf\fR(5). This
+specifies the Linux device for the root partition, this is passed to
+the kernel at boot time. The default is \fI/dev/hda3\fR.
+.TP
+.BR \-v ,\ \-\-verbose
+This option causes \fBybin\fR to be more verbose as it proceeds.
+.TP
+.BR \-f ,\ \-\-force
+This option suppresses any confirmation questions.
+.TP
+.BR \-\-debug
+This option causes \fBybin\fR to output some boring details useful
+only for debugging \fBybin\fR itself.
+.TP
+.BR \-h ,\ \-\-help
+Print out usage information and exit.
+.TP
+.BR \-V ,\ \-\-version
+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
+/etc/yaboot.conf \- boot loader/ybin configuration file
+.fi
+.SH ENVIRONMENT
+.TP
+.B TMPDIR
+.br
+The temporary directory \fBybin\fR will use.
+.SH SECURITY
+The \fByaboot.conf\fR(5) auto generation requires a temporary file, this
+file is created with
+.BR mktemp (1).
+It is important that your system use a secure
+.BR mktemp (1)
+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
+\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
+specified there.
+.SH BUGS
+.B Ybin
+should be able to take care of OpenFirmware variables as needed on IBM
+hardware.
+.SH AUTHORS
+.B ybin
+and this man page was written by Ethan Benson.
+.br
+.B yaboot
+was written by Benjamin Herrenschmidt.
+.SH REPORTING BUGS
+Report bugs to <erbenson@alaska.net>
+.br
+Report bugs in \fByaboot\fR(8) to <benh@kernel.crashing.org>
+.SH SEE ALSO
+.BR bootstrap (8),
+.BR hfsutils (1),
+.BR mkofboot (8),
+.BR mktemp (1),
+.BR nvsetenv (8),
+.BR ofpath (8),
+.BR yaboot (8),
+.BR yaboot.conf (5),
--- /dev/null
+/*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "asm/ppc_asm.tmpl"
+#include "asm/processor.h"
+
+/*
+ * Write any modified data cache blocks out to memory
+ * and invalidate the corresponding instruction cache blocks.
+ * This is a no-op on the 601.
+ *
+ * flush_icache_range(unsigned long start, unsigned long stop)
+ */
+
+CACHE_LINE_SIZE = 32
+LG_CACHE_LINE_SIZE = 5
+
+ .text
+ .globl flush_icache_range
+ .type flush_icache_range,@function
+flush_icache_range:
+ mfspr r5,PVR
+ rlwinm r5,r5,16,16,31
+ cmpi 0,r5,1
+ beqlr /* for 601, do nothing */
+ li r5,CACHE_LINE_SIZE-1
+ andc r3,r3,r5
+ subf r4,r3,r4
+ add r4,r4,r5
+ srwi. r4,r4,LG_CACHE_LINE_SIZE
+ beqlr
+ mtctr r4
+ mr r6,r3
+1: dcbst 0,r3
+ addi r3,r3,CACHE_LINE_SIZE
+ bdnz 1b
+ sync /* wait for dcbst's to get to ram */
+ mtctr r4
+2: icbi 0,r6
+ addi r6,r6,CACHE_LINE_SIZE
+ bdnz 2b
+ sync
+ isync
+ blr
+
+ .text
+ .globl turn_off_mmu
+ .type turn_off_mmu,@function
+turn_off_mmu:
+ lis r0,1f@h
+ ori r0,r0,1f@l
+ mtspr SRR0,r0
+ mfmsr r0
+ lis r2,(~(MSR_DR|MSR_IR))@h
+ ori r2,r2,(~(MSR_DR|MSR_IR))@l
+ and r0,r0,r2
+ mtspr SRR1,r0
+ rfi
+1:
+ blr
--- /dev/null
+/* Handling and parsing of silo.conf
+
+ Copyright (C) 1995 Werner Almesberger
+ 1996 Jakub Jelinek
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "setjmp.h"
+#include "stdarg.h"
+#include "stdlib.h"
+#include "string.h"
+#include "types.h"
+#include "prom.h"
+
+/* Imported functions */
+extern int strcasecmp(const char *s1, const char *s2);
+
+typedef enum {
+ cft_strg, cft_flag, cft_end
+} CONFIG_TYPE;
+
+typedef struct {
+ CONFIG_TYPE type;
+ char *name;
+ void *data;
+} CONFIG;
+
+#define MAX_TOKEN 200
+#define MAX_VAR_NAME MAX_TOKEN
+#define EOF -1
+
+CONFIG cf_options[] =
+{
+ {cft_strg, "device", NULL},
+ {cft_strg, "partition", NULL},
+ {cft_strg, "default", NULL},
+ {cft_strg, "timeout", NULL},
+ {cft_strg, "password", NULL},
+ {cft_flag, "restricted", NULL},
+ {cft_strg, "message", NULL},
+ {cft_strg, "root", NULL},
+ {cft_strg, "ramdisk", NULL},
+ {cft_flag, "read-only", NULL},
+ {cft_flag, "read-write", NULL},
+ {cft_strg, "append", NULL},
+ {cft_strg, "initrd", NULL},
+ {cft_flag, "initrd-prompt", NULL},
+ {cft_strg, "initrd-size", NULL},
+ {cft_flag, "pause-after", NULL},
+ {cft_strg, "pause-message", NULL},
+ {cft_strg, "init-code", NULL},
+ {cft_strg, "init-message", NULL},
+ {cft_strg, "splash", NULL},
+ {cft_strg, "fgcolor", NULL},
+ {cft_strg, "bgcolor", NULL},
+ {cft_end, NULL, NULL}};
+
+CONFIG cf_image[] =
+{
+ {cft_strg, "image", NULL},
+ {cft_strg, "label", NULL},
+ {cft_strg, "alias", NULL},
+ {cft_flag, "single-key", NULL},
+ {cft_flag, "restricted", NULL},
+ {cft_strg, "device", NULL},
+ {cft_strg, "partition", NULL},
+ {cft_strg, "root", NULL},
+ {cft_strg, "ramdisk", NULL},
+ {cft_flag, "read-only", NULL},
+ {cft_flag, "read-write", NULL},
+ {cft_strg, "append", NULL},
+ {cft_strg, "literal", NULL},
+ {cft_strg, "initrd", NULL},
+ {cft_flag, "initrd-prompt", NULL},
+ {cft_strg, "initrd-size", NULL},
+ {cft_flag, "pause-after", NULL},
+ {cft_strg, "pause-message", NULL},
+ {cft_flag, "novideo", NULL},
+ {cft_strg, "splash", NULL},
+ {cft_strg, "sysmap", NULL},
+ {cft_end, NULL, NULL}};
+
+static char flag_set;
+static char *last_token = NULL, *last_item = NULL, *last_value = NULL;
+static int line_num;
+static int back = 0; /* can go back by one char */
+static char *currp = NULL;
+static char *endp = NULL;
+static char *file_name = NULL;
+static CONFIG *curr_table = cf_options;
+static jmp_buf env;
+
+static struct IMAGES {
+ CONFIG table[sizeof (cf_image) / sizeof (cf_image[0])];
+ struct IMAGES *next;
+} *images = NULL;
+
+void cfg_error (char *msg,...)
+{
+ va_list ap;
+
+ va_start (ap, msg);
+ prom_printf ("Config file error: ");
+ prom_vprintf (msg, ap);
+ va_end (ap);
+ prom_printf (" near line %d in file %s\n", line_num, file_name);
+ longjmp (env, 1);
+}
+
+void cfg_warn (char *msg,...)
+{
+ va_list ap;
+
+ va_start (ap, msg);
+ prom_printf ("Config file warning: ");
+ prom_vprintf (msg, ap);
+ va_end (ap);
+ prom_printf (" near line %d in file %s\n", line_num, file_name);
+}
+
+inline int getc ()
+{
+ if (currp == endp)
+ return EOF;
+ return *currp++;
+}
+
+#define next_raw next
+static int next (void)
+{
+ int ch;
+
+ if (!back)
+ return getc ();
+ ch = back;
+ back = 0;
+ return ch;
+}
+
+static void again (int ch)
+{
+ back = ch;
+}
+
+static char *cfg_get_token (void)
+{
+ char buf[MAX_TOKEN + 1];
+ char *here;
+ int ch, escaped;
+
+ if (last_token) {
+ here = last_token;
+ last_token = NULL;
+ return here;
+ }
+ while (1) {
+ while (ch = next (), ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')
+ if (ch == '\n' || ch == '\r')
+ line_num++;
+ if (ch == EOF || ch == (int)NULL)
+ return NULL;
+ if (ch != '#')
+ break;
+ while (ch = next_raw (), (ch != '\n' && ch != '\r'))
+ if (ch == EOF)
+ return NULL;
+ line_num++;
+ }
+ if (ch == '=')
+ return strdup ("=");
+ if (ch == '"') {
+ here = buf;
+ while (here - buf < MAX_TOKEN) {
+ if ((ch = next ()) == EOF)
+ cfg_error ("EOF in quoted string");
+ if (ch == '"') {
+ *here = 0;
+ return strdup (buf);
+ }
+ if (ch == '\\') {
+ ch = next ();
+ switch (ch) {
+ case '"':
+ case '\\':
+ break;
+ case '\n':
+ case '\r':
+ while ((ch = next ()), ch == ' ' || ch == '\t');
+ if (!ch)
+ continue;
+ again (ch);
+ ch = ' ';
+ break;
+ case 'n':
+ ch = '\n';
+ break;
+ default:
+ cfg_error ("Bad use of \\ in quoted string");
+ }
+ } else if ((ch == '\n') || (ch == '\r'))
+ cfg_error ("newline is not allowed in quoted strings");
+ *here++ = ch;
+ }
+ cfg_error ("Quoted string is too long");
+ return 0; /* not reached */
+ }
+ here = buf;
+ escaped = 0;
+ while (here - buf < MAX_TOKEN) {
+ if (escaped) {
+ if (ch == EOF)
+ cfg_error ("\\ precedes EOF");
+ if (ch == '\n')
+ line_num++;
+ else
+ *here++ = ch == '\t' ? ' ' : ch;
+ escaped = 0;
+ } else {
+ if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '#' ||
+ ch == '=' || ch == EOF) {
+ again (ch);
+ *here = 0;
+ return strdup (buf);
+ }
+ if (!(escaped = (ch == '\\')))
+ *here++ = ch;
+ }
+ ch = next ();
+ }
+ cfg_error ("Token is too long");
+ return 0; /* not reached */
+}
+
+static void cfg_return_token (char *token)
+{
+ last_token = token;
+}
+
+static int cfg_next (char **item, char **value)
+{
+ char *this;
+
+ if (last_item) {
+ *item = last_item;
+ *value = last_value;
+ last_item = NULL;
+ return 1;
+ }
+ *value = NULL;
+ if (!(*item = cfg_get_token ()))
+ return 0;
+ if (!strcmp (*item, "="))
+ cfg_error ("Syntax error");
+ if (!(this = cfg_get_token ()))
+ return 1;
+ if (strcmp (this, "=")) {
+ cfg_return_token (this);
+ return 1;
+ }
+ if (!(*value = cfg_get_token ()))
+ cfg_error ("Value expected at EOF");
+ if (!strcmp (*value, "="))
+ cfg_error ("Syntax error after %s", *item);
+ return 1;
+}
+
+#if 0
+// The one and only call to this procedure is commented out
+// below, so we don't need this unless we decide to use it again.
+static void cfg_return (char *item, char *value)
+{
+ last_item = item;
+ last_value = value;
+}
+#endif
+
+static int cfg_set (char *item, char *value)
+{
+ CONFIG *walk;
+
+ if (!strcasecmp (item, "image")) {
+ struct IMAGES **p = &images;
+
+ while (*p)
+ p = &((*p)->next);
+ *p = (struct IMAGES *)malloc (sizeof (struct IMAGES));
+ if (*p == NULL) {
+ prom_printf("malloc error in cfg_set\n");
+ return -1;
+ }
+ (*p)->next = 0;
+ curr_table = ((*p)->table);
+ memcpy (curr_table, cf_image, sizeof (cf_image));
+ }
+ for (walk = curr_table; walk->type != cft_end; walk++) {
+ if (walk->name && !strcasecmp (walk->name, item)) {
+ if (value && walk->type != cft_strg)
+ cfg_warn ("'%s' doesn't have a value", walk->name);
+ else if (!value && walk->type == cft_strg)
+ cfg_warn ("Value expected for '%s'", walk->name);
+ else {
+ if (walk->data)
+ cfg_warn ("Duplicate entry '%s'", walk->name);
+ if (walk->type == cft_flag)
+ walk->data = &flag_set;
+ else if (walk->type == cft_strg)
+ walk->data = value;
+ }
+ break;
+ }
+ }
+ if (walk->type != cft_end)
+ return 1;
+// cfg_return (item, value);
+ return 0;
+}
+
+int cfg_parse (char *cfg_file, char *buff, int len)
+{
+ char *item, *value;
+
+ file_name = cfg_file;
+ currp = buff;
+ endp = currp + len;
+
+ if (setjmp (env))
+ return -1;
+ while (1) {
+ if (!cfg_next (&item, &value))
+ return 0;
+ if (!cfg_set (item, value)) {
+#if DEBUG
+ prom_printf("Can't set item %s to value %s\n", item, value);
+#endif
+ }
+ free (item);
+ }
+}
+
+static char *cfg_get_strg_i (CONFIG * table, char *item)
+{
+ CONFIG *walk;
+
+ for (walk = table; walk->type != cft_end; walk++)
+ if (walk->name && !strcasecmp (walk->name, item))
+ return walk->data;
+ return 0;
+}
+
+char *cfg_get_strg (char *image, char *item)
+{
+ struct IMAGES *p;
+ char *label, *alias;
+ char *ret;
+
+ if (!image)
+ return cfg_get_strg_i (cf_options, item);
+ for (p = images; p; p = p->next) {
+ label = cfg_get_strg_i (p->table, "label");
+ if (!label) {
+ label = cfg_get_strg_i (p->table, "image");
+ alias = strrchr (label, '/');
+ if (alias)
+ label = alias + 1;
+ }
+ alias = cfg_get_strg_i (p->table, "alias");
+ if (!strcmp (label, image) || (alias && !strcmp (alias, image))) {
+ ret = cfg_get_strg_i (p->table, item);
+ if (!ret)
+ ret = cfg_get_strg_i (cf_options, item);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+int cfg_get_flag (char *image, char *item)
+{
+ return !!cfg_get_strg (image, item);
+}
+
+static int printl_count = 0;
+static void printlabel (char *label, int defflag)
+{
+ int len = strlen (label);
+
+ if (!printl_count)
+ prom_printf ("\n");
+ prom_printf ("%s %s",defflag?"*":" ", label);
+ while (len++ < 25)
+ prom_putchar (' ');
+ printl_count++;
+ if (printl_count == 3)
+ printl_count = 0;
+}
+
+void cfg_print_images (void)
+{
+ struct IMAGES *p;
+ char *label, *alias;
+
+ char *ret = cfg_get_strg_i (cf_options, "default");
+ int defflag=0;
+
+ printl_count = 0;
+ for (p = images; p; p = p->next) {
+ label = cfg_get_strg_i (p->table, "label");
+ if (!label) {
+ label = cfg_get_strg_i (p->table, "image");
+ alias = strrchr (label, '/');
+ if (alias)
+ label = alias + 1;
+ }
+ if(!strcmp(ret,label))
+ defflag=1;
+ else
+ defflag=0;
+ alias = cfg_get_strg_i (p->table, "alias");
+ printlabel (label, defflag);
+ if (alias)
+ printlabel (alias, 0);
+ }
+ prom_printf ("\n\nYou can also type in custom image locations, in the form\n"
+ "{prom_path;}partno/path_to_image or {prom_path;}{partno}[start-end]\n"
+ "Example: hd:3,/vmlinux\n\n");
+}
+
+char *cfg_get_default (void)
+{
+ char *label;
+ char *ret = cfg_get_strg_i (cf_options, "default");
+
+ if (ret)
+ return ret;
+ if (!images)
+ return 0;
+ ret = cfg_get_strg_i (images->table, "label");
+ if (!ret) {
+ ret = cfg_get_strg_i (images->table, "image");
+ label = strrchr (ret, '/');
+ if (label)
+ ret = label + 1;
+ }
+ return ret;
+}
--- /dev/null
+/* Prompt handling
+
+ Copyright (C) 1996 Maurizio Plaza
+ 1996 Jakub Jelinek
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "types.h"
+#include "stdarg.h"
+#include "prom.h"
+#include "string.h"
+#include "cfg.h"
+
+#define CMD_LENG 512
+char cbuff[CMD_LENG];
+char passwdbuff[CMD_LENG];
+extern int useconf;
+
+void cmdinit()
+{
+ cbuff[0] = 0;
+ passwdbuff[0] = 0;
+}
+
+void cmdedit (void (*tabfunc) (void), int password)
+{
+ int x, c;
+ char *buff = password ? passwdbuff : cbuff;
+ for (x = 0; x < CMD_LENG - 1; x++) {
+ if (buff[x] == 0)
+ break;
+ else if (password)
+ prom_printf("*");
+ }
+ if (!password)
+ prom_printf(buff, x);
+
+ for (;;) {
+ c = prom_getchar ();
+ if (c == -1)
+ break;
+ if (c == '\n' || c == '\r') {
+ break;
+ }
+ if (c == '\t' && !x && tabfunc)
+ (*tabfunc) ();
+ if (c == '\b' || c == 0x7F) {
+ if (x > 0) {
+ --x;
+ buff[x] = 0;
+ prom_printf("\b \b");
+ }
+ } else if ((c & 0xE0) != 0) {
+ if (x < CMD_LENG - 1) {
+ buff[x] = c;
+ buff[x + 1] = 0;
+ if (password)
+ prom_printf("*");
+ else
+ prom_printf(buff + x);
+ x++;
+ }
+ if (x == 1 && !password && useconf) {
+ if (cfg_get_flag (cbuff, "single-key"))
+ break;
+ }
+ }
+ }
+ buff[x] = 0;
+}
--- /dev/null
+#include "asm/ppc_asm.tmpl"
+#include "asm/processor.h"
+
+/*
+ * Main entry point. should add code to clear BSS and more ...
+ */
+_GLOBAL(_start)
+ lis r10,edata@h
+ ori r10,r10,edata@l
+ lis r11,end@h
+ ori r11,r11,end@l
+ subi r10,r10,4
+ subi r11,r11,4
+ li r0, 0
+1: stwu r0,4(r10)
+ cmp 0,r10,r11
+ bne 1b
+ b yaboot_start
+
+/*
+ * Returns (address we're running at) - (address we were linked at)
+ * for use before the text and data are mapped to KERNELBASE.
+ */
+_GLOBAL(reloc_offset)
+ mflr r0
+ bl 1f
+1: mflr r3
+ lis r4,1b@ha
+ addi r4,r4,1b@l
+ subf r3,r4,r3
+ mtlr r0
+ blr
--- /dev/null
+/* File related stuff
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ctype.h"
+#include "types.h"
+#include "stddef.h"
+#include "stdlib.h"
+#include "file.h"
+#include "prom.h"
+#include "string.h"
+#include "partition.h"
+#include "fs.h"
+
+extern char bootdevice[1024];
+
+/* This function follows the device path in the devtree and separates
+ the device name, partition number, and other datas (mostly file name)
+ the string passed in parameters is changed since 0 are put in place
+ of some separators to terminate the various strings
+ */
+char *
+parse_device_path(char *of_device, char **file_spec, int *partition)
+{
+ char *p, *last;
+
+ if (file_spec)
+ *file_spec = NULL;
+ if (partition)
+ *partition = -1;
+
+ p = strchr(of_device, ':');
+ if (p)
+ *p = 0;
+ else
+ return of_device;
+
+ last = ++p;
+ while(*p && *p != ',') {
+ if (!isdigit (*p)) {
+ p = last;
+ break;
+ }
+ ++p;
+ }
+ if (p != last) {
+ *(p++) = 0;
+ if (partition)
+ *partition = simple_strtol(last, NULL, 10);
+ }
+ if (*p && file_spec)
+ *file_spec = p;
+
+ return of_device;
+
+}
+
+int
+validate_fspec( struct boot_fspec_t* spec,
+ char* default_device,
+ int default_part)
+{
+ if (!spec->file) {
+ spec->file = spec->dev;
+ spec->dev = NULL;
+ }
+ if (spec->part == -1)
+ spec->part = default_part;
+ if (!spec->dev)
+ spec->dev = default_device;
+ if (!spec->file)
+ return FILE_BAD_PATH;
+ else if (spec->file[0] == ',')
+ spec->file++;
+
+ return FILE_ERR_OK;
+}
+
+static int
+file_block_open( struct boot_file_t* file,
+ const char* dev_name,
+ const char* file_name,
+ int partition)
+{
+ struct partition_t* parts;
+ struct partition_t* p;
+ struct partition_t* found;
+
+ parts = partitions_lookup(dev_name);
+ found = NULL;
+
+#if DEBUG
+ if (parts)
+ prom_printf("partitions:\n");
+ else
+ prom_printf("no partitions found.\n");
+#endif
+ for (p = parts; p && !found; p=p->next) {
+#if DEBUG
+ prom_printf("number: %02d, start: 0x%08lx, length: 0x%08lx\n",
+ p->part_number, p->part_start, p->part_size );
+#endif
+ if (partition == -1) {
+ file->fs = fs_open( file, dev_name, p, file_name );
+ if (file->fs != NULL)
+ goto bail;
+ }
+ if ((partition >= 0) && (partition == p->part_number))
+ found = p;
+#if DEBUG
+ if (found)
+ prom_printf(" (match)\n");
+#endif
+ }
+
+ /* Note: we don't skip when found is NULL since we can, in some
+ * cases, let OF figure out a default partition.
+ */
+ DEBUG_F( "Using OF defaults.. (found = 0x%x)\n", found );
+ file->fs = fs_open( file, dev_name, found, file_name );
+
+bail:
+ if (parts)
+ partitions_free(parts);
+
+ return file->fs ? FILE_ERR_OK : FILE_ERR_NOTFOUND;
+}
+
+static int
+file_net_open( struct boot_file_t* file,
+ const char* dev_name,
+ const char* file_name)
+{
+ file->fs = fs_of_netboot;
+ return fs_of_netboot->open(file, dev_name, NULL, file_name);
+}
+
+static int
+default_read( struct boot_file_t* file,
+ unsigned int size,
+ void* buffer)
+{
+ prom_printf("WARNING ! default_read called !\n");
+ return FILE_ERR_EOF;
+}
+
+static int
+default_seek( struct boot_file_t* file,
+ unsigned int newpos)
+{
+ prom_printf("WARNING ! default_seek called !\n");
+ return FILE_ERR_EOF;
+}
+
+static int
+default_close( struct boot_file_t* file)
+{
+ prom_printf("WARNING ! default_close called !\n");
+ return FILE_ERR_OK;
+}
+
+static struct fs_t fs_default =
+{
+ "defaults",
+ NULL,
+ default_read,
+ default_seek,
+ default_close
+};
+
+
+int open_file( const struct boot_fspec_t* spec,
+ struct boot_file_t* file)
+{
+ static char temp[1024];
+ static char temps[64];
+ char *dev_name;
+ char *file_name = NULL;
+ phandle dev;
+ int result;
+ int partition;
+
+ memset(file, 0, sizeof(struct boot_file_t*));
+ file->fs = &fs_default;
+
+ /* Lookup the OF device path */
+ /* First, see if a device was specified for the kernel
+ * if not, we hope that the user wants a kernel on the same
+ * drive and partition as yaboot itself */
+ if (!spec->dev)
+ strcpy(spec->dev, bootdevice);
+ strncpy(temp,spec->dev,1024);
+ dev_name = parse_device_path(temp, &file_name, &partition);
+ if (file_name == NULL)
+ file_name = (char *)spec->file;
+ if (file_name == NULL) {
+ prom_printf("booting without a file name not yet supported !\n");
+ return FILE_ERR_NOTFOUND;
+ }
+ if (partition == -1)
+ partition = spec->part;
+
+#if DEBUG
+ prom_printf("dev_path = %s\nfile_name = %s\npartition = %d\n",
+ dev_name, file_name, partition);
+#endif
+ /* Find OF device phandle */
+ dev = prom_finddevice(dev_name);
+ if (dev == PROM_INVALID_HANDLE) {
+ prom_printf("device not found !\n");
+ return FILE_ERR_NOTFOUND;
+ }
+#if DEBUG
+ prom_printf("dev_phandle = %08lx\n", dev);
+#endif
+ /* Check the kind of device */
+ result = prom_getprop(dev, "device_type", temps, 63);
+ if (result == -1) {
+ prom_printf("can't get <device_type> for device\n");
+ return FILE_ERR_NOTFOUND;
+ }
+ temps[result] = 0;
+ if (!strcmp(temps, "block"))
+ file->device_kind = FILE_DEVICE_BLOCK;
+ else if (!strcmp(temps, "network"))
+ file->device_kind = FILE_DEVICE_NET;
+ else {
+ prom_printf("Unkown device type <%s>\n", temps);
+ return FILE_ERR_NOTFOUND;
+ }
+
+ switch(file->device_kind) {
+ case FILE_DEVICE_BLOCK:
+#if DEBUG
+ prom_printf("device is a block device\n");
+#endif
+ return file_block_open(file, dev_name, file_name, partition);
+ case FILE_DEVICE_NET:
+#if DEBUG
+ prom_printf("device is a network device\n");
+#endif
+ return file_net_open(file, dev_name, file_name);
+ }
+ return 0;
+}
--- /dev/null
+/*
+ FileSystems common definitions
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "stdlib.h"
+#include "fs.h"
+
+extern const struct fs_t of_filesystem;
+extern const struct fs_t of_net_filesystem;
+extern const struct fs_t ext2_filesystem;
+extern const struct fs_t reiserfs_filesystem;
+//extern const struct fs_t iso_filesystem;
+
+/* Filesystem handlers yaboot knows about */
+static const struct fs_t *block_filesystems[] = {
+ &ext2_filesystem, /* ext2 */
+ &reiserfs_filesystem, /* reiserfs */
+ &of_filesystem, /* HFS/HFS+, ISO9660, UDF, UFS */
+ NULL
+};
+
+const struct fs_t *fs_of = &of_filesystem; /* needed by ISO9660 */
+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)
+{
+ const struct fs_t **fs;
+ for( fs = block_filesystems; *fs; fs++ )
+ if( (*fs)->open( file, dev_name, part, file_name ) == FILE_ERR_OK )
+ break;
+
+ return *fs;
+}
--- /dev/null
+/* ext2 filesystem
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+
+ Adapted from quik/silo
+
+ Copyright (C) 1996 Maurizio Plaza
+ 1996 Jakub Jelinek
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ Note: This version is way too slow due to the way we use bmap. This
+ should be replaced by an iterator.
+*/
+
+#include "ctype.h"
+#include "types.h"
+#include "stddef.h"
+#include "file.h"
+#include "prom.h"
+#include "string.h"
+#include "partition.h"
+#include "fs.h"
+
+#define FAST_VERSION
+#define MAX_READ_RANGE 256
+#undef VERBOSE_DEBUG
+
+typedef int FILE;
+#include "linux/ext2_fs.h"
+#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);
+static int ext2_read( struct boot_file_t* file,
+ unsigned int size,
+ void* buffer);
+static int ext2_seek( struct boot_file_t* file,
+ unsigned int newpos);
+static int ext2_close( struct boot_file_t* file);
+
+struct fs_t ext2_filesystem =
+{
+ "ext2",
+ ext2_open,
+ ext2_read,
+ ext2_seek,
+ ext2_close
+};
+
+/* IO manager structure for the ext2 library */
+
+static errcode_t linux_open (const char *name, int flags, io_channel * channel);
+static errcode_t linux_close (io_channel channel);
+static errcode_t linux_set_blksize (io_channel channel, int blksize);
+static errcode_t linux_read_blk (io_channel channel, unsigned long block, int count, void *data);
+static errcode_t linux_write_blk (io_channel channel, unsigned long block, int count, const void *data);
+static errcode_t linux_flush (io_channel channel);
+
+static struct struct_io_manager struct_linux_manager =
+{
+ EXT2_ET_MAGIC_IO_MANAGER,
+ "linux I/O Manager",
+ linux_open,
+ linux_close,
+ linux_set_blksize,
+ linux_read_blk,
+ linux_write_blk,
+ linux_flush
+};
+
+static io_manager linux_io_manager = &struct_linux_manager;
+
+/* Currently, we have a mess between what is in the file structure
+ * and what is stored globally here. I'll clean this up later
+ */
+static int opened = 0; /* We can't open twice ! */
+static unsigned int bs; /* Blocksize */
+static unsigned long long doff; /* Byte offset where partition starts */
+static ino_t root,cwd;
+static ext2_filsys fs = 0;
+static struct boot_file_t* cur_file;
+static char *block_buffer = NULL;
+
+#ifdef FAST_VERSION
+static unsigned long read_range_start;
+static unsigned long read_range_count;
+static unsigned long read_last_logical;
+static unsigned long read_total;
+static unsigned long read_max;
+static struct boot_file_t* read_cur_file;
+static errcode_t read_result;
+static char* read_buffer;
+
+static int read_dump_range(void);
+static int read_iterator(ext2_filsys fs, blk_t *blocknr, int lg_block, void *private);
+#else /* FAST_VERSION */
+static struct ext2_inode cur_inode;
+#endif /* FAST_VERSION */
+
+void com_err (const char *a, long i, const char *fmt,...)
+{
+ prom_printf ((char *) fmt);
+}
+
+static int
+ext2_open( struct boot_file_t* file,
+ const char* dev_name,
+ struct partition_t* part,
+ const char* file_name)
+{
+ int result = 0;
+ static char buffer[1024];
+ int ofopened = 0;
+
+ DEBUG_ENTER;
+ DEBUG_OPEN;
+
+ if (opened) {
+ prom_printf("ext2_open() : fs busy\n");
+ return FILE_ERR_NOTFOUND;
+ }
+ if (file->device_kind != FILE_DEVICE_BLOCK) {
+ prom_printf("Can't open ext2 filesystem on non-block device\n");
+ return FILE_ERR_NOTFOUND;
+ }
+
+ fs = NULL;
+
+ /* We don't care too much about the device block size since we run
+ * thru the deblocker. We may have to change that is we plan to be
+ * compatible with older versions of OF
+ */
+ bs = 1024;
+ doff = 0;
+ if (part)
+ doff = (unsigned long long)(part->part_start) * part->blocksize;
+ cur_file = file;
+
+
+ DEBUG_F("partition offset: %d\n", doff);
+
+ /* Open the OF device for the entire disk */
+ strncpy(buffer, dev_name, 1020);
+ strcat(buffer, ":0");
+
+ DEBUG_F("<%s>\n", buffer);
+
+ file->of_device = prom_open(buffer);
+
+ DEBUG_F("file->of_device = %08lx\n", file->of_device);
+
+ if (file->of_device == PROM_INVALID_HANDLE) {
+
+ DEBUG_F("Can't open device %s\n", file->of_device);
+
+ return FILE_ERR_NOTFOUND;
+ }
+ ofopened = 1;
+
+ /* Open the ext2 filesystem */
+ result = ext2fs_open (buffer, EXT2_FLAG_RW, 0, 0, linux_io_manager, &fs);
+ if (result) {
+
+ if(result == EXT2_ET_BAD_MAGIC)
+ {
+ DEBUG_F( "ext2fs_open returned bad magic loading file %s\n",
+ file );
+ }
+ else
+ {
+ DEBUG_F( "ext2fs_open error #%d while loading file %s\n",
+ result, file_name);
+ }
+
+ goto bail;
+ }
+
+ /* Allocate the block buffer */
+ block_buffer = malloc(fs->blocksize * 2);
+ if (!block_buffer) {
+
+ DEBUG_F("ext2fs: can't alloc block buffer (%d bytes)\n", fs->blocksize * 2);
+
+ goto bail;
+ }
+
+ /* Lookup file by pathname */
+ root = cwd = EXT2_ROOT_INO;
+ result = ext2fs_namei_follow(fs, root, cwd, file_name, &file->inode);
+ if (result) {
+
+ DEBUG_F("ext2fs_namei error #%d while loading file %s\n", result, file_name);
+ goto bail;
+ }
+
+#if 0
+ result = ext2fs_follow_link(fs, root, cwd, file->inode, &file->inode);
+ if (result) {
+
+ DEBUG_F("ext2fs_follow_link error #%d while loading file %s\n", result, file_name);
+
+ goto bail;
+ }
+#endif
+
+#ifndef FAST_VERSION
+ result = ext2fs_read_inode(fs, file->inode, &cur_inode);
+ if (result) {
+
+ DEBUG_F("ext2fs_read_inode error #%d while loading file %s\n", result, file_name);
+
+ goto bail;
+ }
+#endif /* FAST_VERSION */
+ file->pos = 0;
+
+ opened = 1;
+bail:
+ if (!opened) {
+ if (fs)
+ ext2fs_close(fs);
+ fs = NULL;
+ if (ofopened)
+ prom_close(file->of_device);
+ if (block_buffer)
+ free(block_buffer);
+ block_buffer = NULL;
+ cur_file = NULL;
+
+ DEBUG_LEAVE(FILE_ERR_NOTFOUND);
+ return FILE_ERR_NOTFOUND;
+ }
+
+ DEBUG_LEAVE(FILE_ERR_OK);
+ return FILE_ERR_OK;
+}
+
+#ifdef FAST_VERSION
+
+static int
+read_dump_range(void)
+{
+ int count = read_range_count;
+ int size;
+
+#ifdef VERBOSE_DEBUG
+ DEBUG_F(" dumping range: start: 0x%x count: 0x%x\n",
+ read_range_count, read_range_start);
+#endif
+ /* Check if we need to handle a special case for the last block */
+ if ((count * bs) > read_max)
+ count--;
+ if (count) {
+ size = count * bs;
+ read_result = io_channel_read_blk(fs->io, read_range_start, count, read_buffer);
+ if (read_result)
+ return BLOCK_ABORT;
+ read_buffer += size;
+ read_max -= size;
+ read_total += size;
+ read_cur_file->pos += size;
+ read_range_count -= count;
+ read_range_start += count;
+ read_last_logical += count;
+ }
+ /* Handle remaining block */
+ if (read_max && read_range_count) {
+ read_result = io_channel_read_blk(fs->io, read_range_start, 1, block_buffer);
+ if (read_result)
+ return BLOCK_ABORT;
+ memcpy(read_buffer, block_buffer, read_max);
+ read_cur_file->pos += read_max;
+ read_total += read_max;
+ read_max = 0;
+ }
+ read_range_count = read_range_start = 0;
+
+ return (read_max == 0) ? BLOCK_ABORT : 0;
+}
+
+static int
+read_iterator(ext2_filsys fs, blk_t *blocknr, int lg_block, void *private)
+{
+#ifdef VERBOSE_DEBUG
+ DEBUG_F("read_it: p_bloc: 0x%x, l_bloc: 0x%x, f_pos: 0x%x, rng_pos: 0x%x ",
+ *blocknr, lg_block, read_cur_file->pos, read_last_logical);
+#endif
+ if (lg_block < 0) {
+#ifdef VERBOSE_DEBUG
+ DEBUG_F(" <skip lg>\n");
+#endif
+ return 0;
+ }
+
+ /* If we have not reached the start block yet, we skip */
+ if (lg_block < read_cur_file->pos / bs) {
+#ifdef VERBOSE_DEBUG
+ DEBUG_F(" <skip pos>\n");
+#endif
+ return 0;
+ }
+
+ /* If block is contiguous to current range, just extend range,
+ * exit if we pass the remaining bytes count to read
+ */
+ if (read_range_start && read_range_count < MAX_READ_RANGE
+ && (*blocknr == read_range_start + read_range_count)
+ && (lg_block == read_last_logical + read_range_count)) {
+#ifdef VERBOSE_DEBUG
+ DEBUG_F(" block in range\n");
+#endif
+ ++read_range_count;
+ return ((read_range_count * bs) >= read_max) ? BLOCK_ABORT : 0;
+ }
+
+ /* Range doesn't match. Dump existing range */
+ if (read_range_start) {
+#ifdef VERBOSE_DEBUG
+ DEBUG_F(" calling dump range \n");
+#endif
+ if (read_dump_range())
+ return BLOCK_ABORT;
+ }
+
+ /* Here we handle holes in the file */
+ if (lg_block && lg_block != read_last_logical) {
+ unsigned long nzero;
+#ifdef VERBOSE_DEBUG
+ DEBUG_F(" hole from lg_bloc 0x%x\n", read_last_logical);
+#endif
+ if (read_cur_file->pos % bs) {
+ int offset = read_cur_file->pos % bs;
+ int size = bs - offset;
+ if (size > read_max)
+ size = read_max;
+ memset(read_buffer, 0, size);
+ read_max -= size;
+ read_total += size;
+ read_buffer += size;
+ read_cur_file->pos += size;
+ ++read_last_logical;
+ if (read_max == 0)
+ return BLOCK_ABORT;
+ }
+ nzero = (lg_block - read_last_logical) * bs;
+ if (nzero) {
+ if (nzero > read_max)
+ nzero = read_max;
+ memset(read_buffer, 0, nzero);
+ read_max -= nzero;
+ read_total += nzero;
+ read_buffer += nzero;
+ read_cur_file->pos += nzero;
+ if (read_max == 0)
+ return BLOCK_ABORT;
+ }
+ read_last_logical = lg_block;
+ }
+
+ /* If we are not aligned, handle that case */
+ if (read_cur_file->pos % bs) {
+ int offset = read_cur_file->pos % bs;
+ int size = bs - offset;
+#ifdef VERBOSE_DEBUG
+ DEBUG_F(" handle unaligned start\n");
+#endif
+ read_result = io_channel_read_blk(fs->io, *blocknr, 1, block_buffer);
+ if (read_result)
+ return BLOCK_ABORT;
+ if (size > read_max)
+ size = read_max;
+ memcpy(read_buffer, block_buffer + offset, size);
+ read_cur_file->pos += size;
+ read_max -= size;
+ read_total += size;
+ read_buffer += size;
+ read_last_logical = lg_block + 1;
+ return (read_max == 0) ? BLOCK_ABORT : 0;
+ }
+
+ /* If there is still a physical block to add, then create a new range */
+ if (*blocknr) {
+#ifdef VERBOSE_DEBUG
+ DEBUG_F(" new range\n");
+#endif
+ read_range_start = *blocknr;
+ read_range_count = 1;
+ return (bs >= read_max) ? BLOCK_ABORT : 0;
+ }
+
+#ifdef VERBOSE_DEBUG
+ DEBUG_F("\n");
+#endif
+ return 0;
+}
+
+#endif /* FAST_VERSION */
+
+static int
+ext2_read( struct boot_file_t* file,
+ unsigned int size,
+ void* buffer)
+{
+ errcode_t retval;
+
+#ifdef FAST_VERSION
+ if (!opened)
+ return FILE_ERR_NOTFOUND;
+
+
+ DEBUG_F("ext_read() from pos 0x%x, size: 0x%x\n", file->pos, size);
+
+
+ read_cur_file = file;
+ read_range_start = 0;
+ read_range_count = 0;
+ read_last_logical = file->pos / bs;
+ read_total = 0;
+ read_max = size;
+ read_buffer = (unsigned char*)buffer;
+ read_result = 0;
+
+ retval = ext2fs_block_iterate(fs, file->inode, 0, 0, read_iterator, 0);
+ if (retval == BLOCK_ABORT)
+ retval = read_result;
+ if (!retval && read_range_start) {
+#ifdef VERBOSE_DEBUG
+ DEBUG_F("on exit: range_start is 0x%x, calling dump...\n",
+ read_range_start);
+#endif
+ read_dump_range();
+ retval = read_result;
+ }
+ if (retval)
+ prom_printf ("ext2: i/o error %d in read\n", retval);
+
+ return read_total;
+
+#else /* FAST_VERSION */
+ int status;
+ unsigned int read = 0;
+
+ if (!opened)
+ return FILE_ERR_NOTFOUND;
+
+
+ DEBUG_F("ext_read() from pos 0x%x, size: 0x%x\n", file->pos, size);
+
+
+ while(size) {
+ blk_t fblock = file->pos / bs;
+ blk_t pblock;
+ unsigned int blkorig, s, b;
+
+ pblock = 0;
+ status = ext2fs_bmap(fs, file->inode, &cur_inode,
+ block_buffer, 0, fblock, &pblock);
+ if (status) {
+
+ DEBUG_F("ext2fs_bmap(fblock:%d) return: %d\n", fblock, status);
+ return read;
+ }
+ blkorig = fblock * bs;
+ b = file->pos - blkorig;
+ s = ((bs - b) > size) ? size : (bs - b);
+ if (pblock) {
+ unsigned long long pos =
+ ((unsigned long long)pblock) * (unsigned long long)bs;
+ pos += doff;
+ prom_lseek(file->of_device, pos);
+ status = prom_read(file->of_device, block_buffer, bs);
+ if (status != bs) {
+ prom_printf("ext2: io error in read, ex: %d, got: %d\n",
+ bs, status);
+ return read;
+ }
+ } else
+ memset(block_buffer, 0, bs);
+
+ memcpy(buffer, block_buffer + b, s);
+ read += s;
+ size -= s;
+ buffer += s;
+ file->pos += s;
+ }
+ return read;
+#endif /* FAST_VERSION */
+}
+
+static int
+ext2_seek( struct boot_file_t* file,
+ unsigned int newpos)
+{
+ if (!opened)
+ return FILE_ERR_NOTFOUND;
+
+ file->pos = newpos;
+ return FILE_ERR_OK;
+}
+
+static int
+ext2_close( struct boot_file_t* file)
+{
+ if (!opened)
+ return FILE_ERR_NOTFOUND;
+
+ if (block_buffer)
+ free(block_buffer);
+ block_buffer = NULL;
+
+ if (fs)
+ ext2fs_close(fs);
+ fs = NULL;
+
+ prom_close(file->of_device);
+
+ opened = 0;
+
+ return 0;
+}
+
+static errcode_t linux_open (const char *name, int flags, io_channel * channel)
+{
+ io_channel io;
+
+
+ if (!name)
+ return EXT2_ET_BAD_DEVICE_NAME;
+ io = (io_channel) malloc (sizeof (struct struct_io_channel));
+ if (!io)
+ return EXT2_ET_BAD_DEVICE_NAME;
+ memset (io, 0, sizeof (struct struct_io_channel));
+ io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
+ io->manager = linux_io_manager;
+ io->name = (char *) malloc (strlen (name) + 1);
+ strcpy (io->name, name);
+ io->block_size = bs;
+ io->read_error = 0;
+ io->write_error = 0;
+ *channel = io;
+
+ return 0;
+}
+
+static errcode_t linux_close (io_channel channel)
+{
+ free(channel);
+ return 0;
+}
+
+static errcode_t linux_set_blksize (io_channel channel, int blksize)
+{
+ channel->block_size = bs = blksize;
+ if (block_buffer) {
+ free(block_buffer);
+ block_buffer = malloc(bs * 2);
+ }
+ return 0;
+}
+
+static errcode_t linux_read_blk (io_channel channel, unsigned long block, int count, void *data)
+{
+ int size;
+ unsigned long long tempb;
+
+ if (count == 0)
+ return 0;
+
+ tempb = (((unsigned long long) block) *
+ ((unsigned long long)bs)) + (unsigned long long)doff;
+ size = (count < 0) ? -count : count * bs;
+ prom_lseek(cur_file->of_device, tempb);
+ if (prom_read(cur_file->of_device, data, size) != size) {
+ prom_printf ("\nRead error on block %d", block);
+ return EXT2_ET_SHORT_READ;
+ }
+ return 0;
+}
+
+static errcode_t linux_write_blk (io_channel channel, unsigned long block, int count, const void *data)
+{
+ return 0;
+}
+
+static errcode_t linux_flush (io_channel channel)
+{
+ return 0;
+}
+
--- /dev/null
+/* iso9660 filesystem (placeholder)
+
+ Copyright (C) 1999 Benjamin Herrenschnidt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ctype.h"
+#include "types.h"
+#include "stddef.h"
+#include "file.h"
+#include "prom.h"
+#include "string.h"
+#include "partition.h"
+#include "fs.h"
+
+
+static int iso_open( struct boot_file_t* file,
+ const char* dev_name,
+ struct partition_t* part,
+ const char* file_name);
+static int iso_read( struct boot_file_t* file,
+ unsigned int size,
+ void* buffer);
+static int iso_seek( struct boot_file_t* file,
+ unsigned int newpos);
+static int iso_close( struct boot_file_t* file);
+
+struct fs_t iso_filesystem =
+{
+ "iso9660",
+ iso_open,
+ iso_read,
+ iso_seek,
+ iso_close
+};
+
+static int
+iso_open( struct boot_file_t* file,
+ const char* dev_name,
+ struct partition_t* part,
+ const char* file_name)
+{
+ return FILE_ERR_NOTFOUND;
+}
+
+static int
+iso_read( struct boot_file_t* file,
+ unsigned int size,
+ void* buffer)
+{
+ return FILE_ERR_NOTFOUND;
+}
+
+static int
+iso_seek( struct boot_file_t* file,
+ unsigned int newpos)
+{
+ return FILE_ERR_NOTFOUND;
+}
+
+static int
+iso_close( struct boot_file_t* file)
+{
+ return 0;
+}
--- /dev/null
+/* OpenFirmware-based filesystem
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ BrokenFirmware cannot "read" from the network. We use tftp "load" method
+ for network boot for now, we may provide our own NFS implementation in
+ a later version. That means that we allocate a huge block of memory for
+ the entire file before loading it. We use the location where the kernel puts
+ RTAS, it's not used by the bootloader and if freed when the kernel is booted.
+ This will have to be changed if we plan to instanciate RTAS in the bootloader
+ itself
+
+*/
+
+#include "ctype.h"
+#include "types.h"
+#include "stddef.h"
+#include "stdlib.h"
+#include "file.h"
+#include "prom.h"
+#include "string.h"
+#include "partition.h"
+#include "fs.h"
+
+
+#define LOAD_BUFFER_POS 0x600000
+#define LOAD_BUFFER_SIZE 0x400000
+
+static int of_open( struct boot_file_t* file,
+ const char* dev_name,
+ struct partition_t* part,
+ const char* file_name);
+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_read( struct boot_file_t* file,
+ unsigned int size,
+ void* buffer);
+static int of_net_seek( struct boot_file_t* file,
+ unsigned int newpos);
+
+
+struct fs_t of_filesystem =
+{
+ "built-in",
+ of_open,
+ of_read,
+ of_seek,
+ of_close
+};
+
+struct fs_t of_net_filesystem =
+{
+ "built-in network",
+ of_net_open,
+ of_net_read,
+ of_net_seek,
+ of_close
+};
+
+
+
+static int
+of_open( struct boot_file_t* file,
+ const char* dev_name,
+ struct partition_t* part,
+ const char* file_name)
+{
+ static char buffer[1024];
+
+ DEBUG_ENTER;
+ DEBUG_OPEN;
+
+ strncpy(buffer, dev_name, 1000);
+ strcat(buffer, ":");
+ if (part) {
+ char pn[3];
+ sprintf(pn, "%02d", part->part_number);
+ strcat(buffer, pn);
+ }
+ if (file_name && strlen(file_name)) {
+ if (part)
+ strcat(buffer, ",");
+ strcat(buffer, file_name);
+ }
+
+ DEBUG_F("<%s>\n", buffer);
+
+ file->of_device = prom_open(buffer);
+
+ DEBUG_F("file->of_device = %08lx\n", file->of_device);
+
+ file->pos = 0;
+ file->buffer = NULL;
+ if ((file->of_device == PROM_INVALID_HANDLE) || (file->of_device == 0))
+ {
+ DEBUG_LEAVE(FILE_ERR_NOTFOUND);
+ return FILE_ERR_NOTFOUND;
+ }
+
+ DEBUG_LEAVE(FILE_ERR_OK);
+ return FILE_ERR_OK;
+}
+
+static int
+of_net_open( struct boot_file_t* file,
+ const char* dev_name,
+ struct partition_t* part,
+ const char* file_name)
+{
+ static char buffer[1024];
+
+ DEBUG_ENTER;
+ DEBUG_OPEN;
+
+ strncpy(buffer, dev_name, 1000);
+ strcat(buffer, ":0");
+ if (file_name && strlen(file_name)) {
+ strcat(buffer, ",");
+ strcat(buffer, file_name);
+ }
+
+ DEBUG_F("<%s>\n", buffer);
+
+ file->of_device = prom_open(buffer);
+
+ DEBUG_F("file->of_device = %08lx\n", file->of_device);
+
+ file->pos = 0;
+ if ((file->of_device == PROM_INVALID_HANDLE) || (file->of_device == 0))
+ {
+ DEBUG_LEAVE(FILE_ERR_NOTFOUND);
+ return FILE_ERR_NOTFOUND;
+ }
+
+ file->buffer = prom_claim((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);
+ DEBUG_LEAVE(FILE_ERR_NOTFOUND);
+ return FILE_ERR_NOTFOUND;
+ }
+ memset(file->buffer, 0, LOAD_BUFFER_SIZE);
+
+ DEBUG_F("TFP...\n");
+
+ file->len = prom_loadmethod(file->of_device, file->buffer);
+
+ DEBUG_F("result: %d\n", file->len);
+
+
+ DEBUG_LEAVE(FILE_ERR_OK);
+ return FILE_ERR_OK;
+}
+
+static int
+of_read( struct boot_file_t* file,
+ unsigned int size,
+ void* buffer)
+{
+ unsigned int count;
+
+ count = prom_read(file->of_device, buffer, size);
+ file->pos += count;
+ return count;
+}
+
+static int
+of_net_read( struct boot_file_t* file,
+ unsigned int size,
+ void* buffer)
+{
+ unsigned int count, av;
+
+ av = file->len - file->pos;
+ count = size > av ? av : size;
+ memcpy(buffer, file->buffer + file->pos, count);
+ file->pos += count;
+ return count;
+}
+
+static int
+of_seek( struct boot_file_t* file,
+ unsigned int newpos)
+{
+ if (prom_seek(file->of_device, newpos)) {
+ file->pos = newpos;
+ return FILE_ERR_OK;
+ }
+
+ return FILE_CANT_SEEK;
+}
+
+static int
+of_net_seek( struct boot_file_t* file,
+ unsigned int newpos)
+{
+ file->pos = (newpos > file->len) ? file->len : newpos;
+ return FILE_ERR_OK;
+}
+
+static int
+of_close( struct boot_file_t* file)
+{
+
+ DEBUG_ENTER;
+ DEBUG_F("<@0x%08lx>n", file->of_device);
+
+ if (file->buffer) {
+ prom_release(file->buffer, LOAD_BUFFER_SIZE);
+ }
+ prom_close(file->of_device);
+
+ DEBUG_LEAVE(0);
+
+ return 0;
+}
+
--- /dev/null
+/* ReiserFS filesystem
+
+ Copyright (C) 2001 Jeffrey Mahoney (jeffm@suse.com)
+
+ Adapted from GRUB
+
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+#include "types.h"
+#include "ctype.h"
+#include "string.h"
+#include "stdlib.h"
+#include "fs.h"
+#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_read( struct boot_file_t *file, unsigned int size,
+
+ void *buffer );
+static int reiserfs_seek( struct boot_file_t *file, unsigned int newpos );
+static int reiserfs_close( struct boot_file_t *file );
+
+struct fs_t reiserfs_filesystem = {
+ name:"reiserfs",
+ open:reiserfs_open,
+ read:reiserfs_read,
+ seek:reiserfs_seek,
+ close:reiserfs_close
+};
+
+static int reiserfs_read_super( void );
+static int reiserfs_open_file( char *dirname );
+static int reiserfs_read_data( char *buf, __u32 len );
+
+
+static struct reiserfs_state reiserfs;
+static struct reiserfs_state *INFO = &reiserfs;
+
+/* Adapted from GRUB: */
+static char FSYS_BUF[FSYSREISER_CACHE_SIZE];
+int errnum;
+
+
+static int
+reiserfs_open( struct boot_file_t *file, const char *dev_name,
+ struct partition_t *part, const char *file_name )
+{
+ static char buffer[1024];
+
+ DEBUG_ENTER;
+ DEBUG_OPEN;
+
+ memset( INFO, 0, sizeof(struct reiserfs_state) );
+ INFO->file = file;
+
+ if (part)
+ {
+ DEBUG_F( "Determining offset for partition %d\n", part->part_number );
+ INFO->partition_offset = ((__u64)(part->part_start)) * ((__u64)part->blocksize);
+ DEBUG_F( "%Lu = %lu * %hu\n", INFO->partition_offset,
+ part->part_start,
+ part->blocksize );
+ }
+ else
+ INFO->partition_offset = 0;
+
+ sprintf( buffer, "%s:%d", dev_name, /*part ? part->part_number :*/ 0 );
+ 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 );
+
+ if ( file->of_device == PROM_INVALID_HANDLE || file->of_device == NULL )
+ {
+ DEBUG_F( "Can't open device %s\n", file->of_device );
+ DEBUG_LEAVE(FILE_ERR_NOTFOUND);
+ return FILE_ERR_NOTFOUND;
+ }
+
+ DEBUG_F( "%s was successfully opened\n" );
+
+ if ( reiserfs_read_super() != 1 )
+ {
+ DEBUG_F( "Couldn't open ReiserFS @ %s/%Lu\n", buffer, INFO->partition_offset );
+ prom_close( file->of_device );
+ DEBUG_LEAVE(FILE_ERR_NOTFOUND);
+ return FILE_ERR_NOTFOUND;
+ }
+
+ DEBUG_F( "Attempting to open %s\n", file_name );
+ strcpy(buffer, file_name); /* reiserfs_open_file modifies argument */
+ if( reiserfs_open_file(buffer) == 0 )
+ {
+ DEBUG_F( "reiserfs_open_file failed. errnum = %d\n", errnum );
+ prom_close( file->of_device );
+ DEBUG_LEAVE(FILE_ERR_NOTFOUND);
+ return FILE_ERR_NOTFOUND;
+ }
+
+ DEBUG_F( "Successfully opened %s\n", file_name );
+
+ DEBUG_LEAVE(FILE_ERR_OK);
+ return FILE_ERR_OK;
+}
+
+static int
+reiserfs_read( struct boot_file_t *file, unsigned int size, void *buffer )
+{
+ return reiserfs_read_data( buffer, size );
+}
+
+static int
+reiserfs_seek( struct boot_file_t *file, unsigned int newpos )
+{
+ file->pos = newpos;
+ return FILE_ERR_OK;
+}
+
+static int
+reiserfs_close( struct boot_file_t *file )
+{
+ if( file->of_device )
+ {
+ prom_close(file->of_device);
+ file->of_device = 0;
+ }
+ return FILE_ERR_OK;
+}
+
+
+static __inline__ __u32
+log2( __u32 word )
+{
+ int i = 0;
+ while( word && (word & (1 << ++i)) == 0 );
+ return i;
+}
+
+static __inline__ int
+is_power_of_two( unsigned long word )
+{
+ return ( word & -word ) == word;
+}
+
+static int
+read_disk_block( struct boot_file_t *file, __u32 block, __u32 start,
+ __u32 length, void *buf )
+{
+ __u16 fs_blocksize = INFO->blocksize == 0 ? REISERFS_OLD_BLOCKSIZE
+ : INFO->blocksize;
+ unsigned long long pos = block * fs_blocksize;
+ pos += INFO->partition_offset + start;
+ DEBUG_F( "Reading %lu bytes, starting at block %lu, disk offset %Lu\n",
+ length, block, pos );
+ prom_lseek( file->of_device, pos );
+ return prom_read( file->of_device, buf, length );
+}
+
+
+static int
+journal_read( __u32 block, __u32 len, char *buffer )
+{
+ return read_disk_block( INFO->file,
+ (INFO->journal_block + block), 0,
+ len, buffer );
+}
+
+/* Read a block from ReiserFS file system, taking the journal into
+ * account. If the block nr is in the journal, the block from the
+ * journal taken.
+ */
+static int
+block_read( __u32 blockNr, __u32 start, __u32 len, char *buffer )
+{
+ __u32 transactions = INFO->journal_transactions;
+ __u32 desc_block = INFO->journal_first_desc;
+ __u32 journal_mask = INFO->journal_block_count - 1;
+ __u32 translatedNr = blockNr;
+ __u32 *journal_table = JOURNAL_START;
+
+// DEBUG_F( "block_read( %u, %u, %u, ..)\n", blockNr, start, len );
+
+ while ( transactions-- > 0 )
+ {
+ int i = 0;
+ int j_len;
+
+ if ( *journal_table != 0xffffffff )
+ {
+ /* Search for the blockNr in cached journal */
+ j_len = le32_to_cpu(*journal_table++);
+ while ( i++ < j_len )
+ {
+ if ( le32_to_cpu(*journal_table++) == blockNr )
+ {
+ journal_table += j_len - i;
+ goto found;
+ }
+ }
+ }
+ else
+ {
+ /* This is the end of cached journal marker. The remaining
+ * transactions are still on disk. */
+ struct reiserfs_journal_desc desc;
+ struct reiserfs_journal_commit commit;
+
+ if ( !journal_read( desc_block, sizeof(desc), (char *) &desc ) )
+ return 0;
+
+ j_len = le32_to_cpu(desc.j_len);
+ while ( i < j_len && i < JOURNAL_TRANS_HALF )
+ if ( le32_to_cpu(desc.j_realblock[i++]) == blockNr )
+ goto found;
+
+ if ( j_len >= JOURNAL_TRANS_HALF )
+ {
+ int commit_block = ( desc_block + 1 + j_len ) & journal_mask;
+
+ if ( !journal_read( commit_block,
+ sizeof(commit), (char *) &commit ) )
+ return 0;
+
+ while ( i < j_len )
+ if ( le32_to_cpu(commit.j_realblock[i++ - JOURNAL_TRANS_HALF]) == blockNr )
+ goto found;
+ }
+ }
+ goto not_found;
+
+ found:
+ translatedNr =
+ INFO->journal_block + ( ( desc_block + i ) & journal_mask );
+
+ DEBUG_F( "block_read: block %u is mapped to journal block %u.\n",
+ blockNr, translatedNr - INFO->journal_block );
+
+ /* We must continue the search, as this block may be overwritten in
+ * later transactions. */
+ not_found:
+ desc_block = (desc_block + 2 + j_len) & journal_mask;
+ }
+
+ return read_disk_block( INFO->file, translatedNr, start, len, buffer );
+}
+
+/* Init the journal data structure. We try to cache as much as
+ * possible in the JOURNAL_START-JOURNAL_END space, but if it is full
+ * we can still read the rest from the disk on demand.
+ *
+ * The first number of valid transactions and the descriptor block of the
+ * first valid transaction are held in INFO. The transactions are all
+ * adjacent, but we must take care of the journal wrap around.
+ */
+static int
+journal_init( void )
+{
+ struct reiserfs_journal_header header;
+ struct reiserfs_journal_desc desc;
+ struct reiserfs_journal_commit commit;
+ __u32 block_count = INFO->journal_block_count;
+ __u32 desc_block;
+ __u32 commit_block;
+ __u32 next_trans_id;
+ __u32 *journal_table = JOURNAL_START;
+
+ journal_read( block_count, sizeof ( header ), ( char * ) &header );
+ desc_block = le32_to_cpu(header.j_first_unflushed_offset);
+ if ( desc_block >= block_count )
+ return 0;
+
+ INFO->journal_transactions = 0;
+ INFO->journal_first_desc = desc_block;
+ next_trans_id = le32_to_cpu(header.j_last_flush_trans_id) + 1;
+
+ DEBUG_F( "journal_init: last flushed %u\n", le32_to_cpu(header.j_last_flush_trans_id) );
+
+ while ( 1 )
+ {
+ journal_read( desc_block, sizeof(desc), (char *) &desc );
+ if ( strcmp( JOURNAL_DESC_MAGIC, desc.j_magic ) != 0
+ || desc.j_trans_id != next_trans_id
+ || desc.j_mount_id != header.j_mount_id )
+ /* no more valid transactions */
+ break;
+
+ commit_block = ( desc_block + le32_to_cpu(desc.j_len) + 1 ) & ( block_count - 1 );
+ journal_read( commit_block, sizeof(commit), (char *) &commit );
+ if ( desc.j_trans_id != commit.j_trans_id
+ || desc.j_len != commit.j_len )
+ /* no more valid transactions */
+ break;
+
+
+ DEBUG_F( "Found valid transaction %u/%u at %u.\n",
+ le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id),
+ desc_block );
+
+
+ next_trans_id++;
+ if ( journal_table < JOURNAL_END )
+ {
+ if ( ( journal_table + 1 + le32_to_cpu(desc.j_len) ) >= JOURNAL_END )
+ {
+ /* The table is almost full; mark the end of the cached * *
+ * journal. */
+ *journal_table = 0xffffffff;
+ journal_table = JOURNAL_END;
+ }
+ else
+ {
+ int i;
+
+ /* Cache the length and the realblock numbers in the table. *
+ * The block number of descriptor can easily be computed. *
+ * and need not to be stored here. */
+ *journal_table++ = desc.j_len;
+ for ( i = 0; i < le32_to_cpu(desc.j_len) && i < JOURNAL_TRANS_HALF; i++ )
+ {
+ *journal_table++ = desc.j_realblock[i];
+
+ DEBUG_F( "block %u is in journal %u.\n",
+ le32_to_cpu(desc.j_realblock[i]), desc_block );
+
+ }
+ for ( ; i < le32_to_cpu(desc.j_len); i++ )
+ {
+ *journal_table++ =
+ commit.j_realblock[i - JOURNAL_TRANS_HALF];
+
+ DEBUG_F( "block %u is in journal %u.\n",
+ le32_to_cpu(commit.j_realblock[i - JOURNAL_TRANS_HALF]),
+ desc_block );
+
+ }
+ }
+ }
+ desc_block = (commit_block + 1) & (block_count - 1);
+ }
+
+ DEBUG_F( "Transaction %u/%u at %u isn't valid.\n",
+ le32_to_cpu(desc.j_trans_id), le32_to_cpu(desc.j_mount_id),
+ desc_block );
+
+
+ INFO->journal_transactions
+ = next_trans_id - le32_to_cpu(header.j_last_flush_trans_id) - 1;
+ return errnum == 0;
+}
+
+/* check filesystem types and read superblock into memory buffer */
+static int
+reiserfs_read_super( void )
+{
+ struct reiserfs_super_block super;
+ __u64 superblock = REISERFS_SUPERBLOCK_BLOCK;
+
+ read_disk_block( INFO->file, superblock, 0, sizeof(super), &super );
+
+ DEBUG_F( "Found super->magic %s\n", super.s_magic );
+
+ if( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
+ strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
+ {
+ /* Try old super block position */
+ superblock = REISERFS_OLD_SUPERBLOCK_BLOCK;
+ read_disk_block( INFO->file, superblock, 0, sizeof (super), &super );
+
+ if ( strcmp( REISER2FS_SUPER_MAGIC_STRING, super.s_magic ) != 0 &&
+ strcmp( REISERFS_SUPER_MAGIC_STRING, super.s_magic ) != 0 )
+ {
+ /* pre journaling super block - untested */
+ if ( strcmp( REISERFS_SUPER_MAGIC_STRING,
+ (char *) ((__u32) &super + 20 ) ) != 0 )
+ return 0;
+
+ super.s_blocksize = cpu_to_le16(REISERFS_OLD_BLOCKSIZE);
+ super.s_journal_block = 0;
+ super.s_version = 0;
+ }
+ }
+
+ DEBUG_F( "ReiserFS superblock data:\n" );
+ DEBUG_F( "Block count: %lu\n", le32_to_cpu(super.s_block_count) )
+ DEBUG_F( "Free blocks: %lu\n", le32_to_cpu(super.s_free_blocks) );
+ DEBUG_F( "Journal block: %lu\n", le32_to_cpu(super.s_journal_block) );
+ DEBUG_F( "Journal size (in blocks): %lu\n",
+ le32_to_cpu(super.s_orig_journal_size) );
+ DEBUG_F( "Root block: %lu\n\n", le32_to_cpu(super.s_root_block) );
+
+
+ INFO->version = le16_to_cpu(super.s_version);
+ INFO->blocksize = le16_to_cpu(super.s_blocksize);
+ INFO->blocksize_shift = log2( INFO->blocksize );
+
+ INFO->journal_block = le32_to_cpu(super.s_journal_block);
+ INFO->journal_block_count = le32_to_cpu(super.s_orig_journal_size);
+
+ INFO->cached_slots = (FSYSREISER_CACHE_SIZE >> INFO->blocksize_shift) - 1;
+
+ /* At this point, we've found a valid superblock. If we run into problems
+ * mounting the FS, the user should probably know. */
+
+ /* A few sanity checks ... */
+ if ( INFO->version > REISERFS_MAX_SUPPORTED_VERSION )
+ {
+ prom_printf( "ReiserFS: Unsupported version field: %u\n",
+ INFO->version );
+ return 0;
+ }
+
+ if ( INFO->blocksize < FSYSREISER_MIN_BLOCKSIZE
+ || INFO->blocksize > FSYSREISER_MAX_BLOCKSIZE )
+ {
+ prom_printf( "ReiserFS: Unsupported block size: %u\n",
+ INFO->blocksize );
+ return 0;
+ }
+
+ /* Setup the journal.. */
+ if ( INFO->journal_block != 0 )
+ {
+ if ( !is_power_of_two( INFO->journal_block_count ) )
+ {
+ prom_printf( "ReiserFS: Unsupported journal size, "
+ "not a power of 2: %lu\n",
+ INFO->journal_block_count );
+ return 0;
+ }
+
+ journal_init();
+ /* Read in super block again, maybe it is in the journal */
+ block_read( superblock, 0, sizeof (struct reiserfs_super_block),
+ (char *) &super );
+ }
+
+ /* Read in the root block */
+ if ( !block_read( le32_to_cpu(super.s_root_block), 0,
+ INFO->blocksize, ROOT ) )
+ {
+ prom_printf( "ReiserFS: Failed to read in root block\n" );
+ return 0;
+ }
+
+ /* The root node is always the "deepest", so we can
+ determine the hieght of the tree using it. */
+ INFO->tree_depth = blkh_level(BLOCKHEAD(ROOT));
+
+
+ DEBUG_F( "root read_in: block=%u, depth=%u\n",
+ le32_to_cpu(super.s_root_block), INFO->tree_depth );
+
+ if ( INFO->tree_depth >= REISERFS_MAX_TREE_HEIGHT )
+ {
+ prom_printf( "ReiserFS: Unsupported tree depth (too deep): %u\n",
+ INFO->tree_depth );
+ return 0;
+ }
+
+ if ( INFO->tree_depth == BLKH_LEVEL_LEAF )
+ {
+ /* There is only one node in the whole filesystem, which is
+ simultanously leaf and root */
+ memcpy( LEAF, ROOT, INFO->blocksize );
+ }
+ return 1;
+}
+
+/***************** TREE ACCESSING METHODS *****************************/
+
+/* I assume you are familiar with the ReiserFS tree, if not go to
+ * http://devlinux.com/projects/reiserfs/
+ *
+ * My tree node cache is organized as following
+ * 0 ROOT node
+ * 1 LEAF node (if the ROOT is also a LEAF it is copied here
+ * 2-n other nodes on current path from bottom to top.
+ * if there is not enough space in the cache, the top most are
+ * omitted.
+ *
+ * I have only two methods to find a key in the tree:
+ * search_stat(dir_id, objectid) searches for the stat entry (always
+ * the first entry) of an object.
+ * next_key() gets the next key in tree order.
+ *
+ * This means, that I can only sequential reads of files are
+ * efficient, but this really doesn't hurt for grub.
+ */
+
+/* Read in the node at the current path and depth into the node cache.
+ * You must set INFO->blocks[depth] before.
+ */
+static char *
+read_tree_node( __u32 blockNr, __u16 depth )
+{
+ char *cache = CACHE(depth);
+ int num_cached = INFO->cached_slots;
+
+ if ( depth < num_cached )
+ {
+ /* This is the cached part of the path.
+ Check if same block is needed. */
+ if ( blockNr == INFO->blocks[depth] )
+ return cache;
+ }
+ else
+ cache = CACHE(num_cached);
+
+ DEBUG_F( " next read_in: block=%u (depth=%u)\n", blockNr, depth );
+
+ if ( !block_read( blockNr, 0, INFO->blocksize, cache ) )
+ {
+ DEBUG_F( "block_read failed\n" );
+ return 0;
+ }
+
+ DEBUG_F( "FOUND: blk_level=%u, blk_nr_item=%u, blk_free_space=%u\n",
+ blkh_level(BLOCKHEAD(cache)),
+ blkh_nr_item(BLOCKHEAD(cache)),
+ le16_to_cpu(BLOCKHEAD(cache)->blk_free_space) );
+
+ /* Make sure it has the right node level */
+ if ( blkh_level(BLOCKHEAD(cache)) != depth )
+ {
+ DEBUG_F( "depth = %u != %u\n", blkh_level(BLOCKHEAD(cache)), depth );
+ DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+ errnum = FILE_ERR_BAD_FSYS;
+ return 0;
+ }
+
+ INFO->blocks[depth] = blockNr;
+ return cache;
+}
+
+/* Get the next key, i.e. the key following the last retrieved key in
+ * tree order. INFO->current_ih and
+ * INFO->current_info are adapted accordingly. */
+static int
+next_key( void )
+{
+ __u16 depth;
+ struct item_head *ih = INFO->current_ih + 1;
+ char *cache;
+
+
+ DEBUG_F( "next_key:\n old ih: key %u:%u:%u:%u version:%u\n",
+ le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
+ le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
+ le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset),
+ le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness),
+ ih_version(INFO->current_ih) );
+
+
+ if ( ih == &ITEMHEAD[blkh_nr_item(BLOCKHEAD( LEAF ))] )
+ {
+ depth = BLKH_LEVEL_LEAF;
+ /* The last item, was the last in the leaf node. * Read in the next
+ * * block */
+ do
+ {
+ if ( depth == INFO->tree_depth )
+ {
+ /* There are no more keys at all. * Return a dummy item with
+ * * MAX_KEY */
+ ih =
+ ( struct item_head * )
+ &BLOCKHEAD( LEAF )->blk_right_delim_key;
+ goto found;
+ }
+ depth++;
+
+ DEBUG_F( " depth=%u, i=%u\n", depth, INFO->next_key_nr[depth] );
+
+ }
+ while ( INFO->next_key_nr[depth] == 0 );
+
+ if ( depth == INFO->tree_depth )
+ cache = ROOT;
+ else if ( depth <= INFO->cached_slots )
+ cache = CACHE( depth );
+ else
+ {
+ cache = read_tree_node( INFO->blocks[depth], --depth );
+ if ( !cache )
+ return 0;
+ }
+
+ do
+ {
+ __u16 nr_item = blkh_nr_item(BLOCKHEAD( cache ));
+ int key_nr = INFO->next_key_nr[depth]++;
+
+
+ DEBUG_F( " depth=%u, i=%u/%u\n", depth, key_nr, nr_item );
+
+ if ( key_nr == nr_item )
+ /* This is the last item in this block, set the next_key_nr *
+ * to 0 */
+ INFO->next_key_nr[depth] = 0;
+
+ cache =
+ read_tree_node( dc_block_number( &(DC( cache )[key_nr])),
+ --depth );
+ if ( !cache )
+ return 0;
+ }
+ while ( depth > BLKH_LEVEL_LEAF );
+
+ ih = ITEMHEAD;
+ }
+ found:
+ INFO->current_ih = ih;
+ INFO->current_item = &LEAF[ih_location(ih)];
+
+ DEBUG_F( " new ih: key %u:%u:%u:%u version:%u\n",
+ le32_to_cpu(INFO->current_ih->ih_key.k_dir_id),
+ le32_to_cpu(INFO->current_ih->ih_key.k_objectid),
+ le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_offset),
+ le32_to_cpu(INFO->current_ih->ih_key.u.k_offset_v1.k_uniqueness),
+ ih_version(INFO->current_ih) );
+
+ return 1;
+}
+
+/* preconditions: reiserfs_read_super already executed, therefore
+ * INFO block is valid
+ * returns: 0 if error (errnum is set),
+ * nonzero iff we were able to find the key successfully.
+ * postconditions: on a nonzero return, the current_ih and
+ * current_item fields describe the key that equals the
+ * searched key. INFO->next_key contains the next key after
+ * the searched key.
+ * side effects: messes around with the cache.
+ */
+static int
+search_stat( __u32 dir_id, __u32 objectid )
+{
+ char *cache;
+ int depth;
+ int nr_item;
+ int i;
+ struct item_head *ih;
+
+
+ DEBUG_F( "search_stat:\n key %u:%u:0:0\n", le32_to_cpu(dir_id),
+ le32_to_cpu(objectid) );
+
+
+ depth = INFO->tree_depth;
+ cache = ROOT;
+
+ DEBUG_F( "depth = %d\n", depth );
+ while ( depth > BLKH_LEVEL_LEAF )
+ {
+ struct key *key;
+
+ nr_item = blkh_nr_item(BLOCKHEAD( cache ));
+
+ key = KEY( cache );
+
+ for ( i = 0; i < nr_item; i++ )
+ {
+ if (le32_to_cpu(key->k_dir_id) > le32_to_cpu(dir_id)
+ || (key->k_dir_id == dir_id
+ && (le32_to_cpu(key->k_objectid) > le32_to_cpu(objectid)
+ || (key->k_objectid == objectid
+ && (key->u.k_offset_v1.k_offset
+ | key->u.k_offset_v1.k_uniqueness) > 0))))
+ break;
+ key++;
+ }
+
+
+ DEBUG_F( " depth=%d, i=%d/%d\n", depth, i, nr_item );
+
+ INFO->next_key_nr[depth] = ( i == nr_item ) ? 0 : i + 1;
+ cache = read_tree_node( dc_block_number(&(DC(cache)[i])), --depth );
+ if ( !cache )
+ return 0;
+ }
+
+ /* cache == LEAF */
+ nr_item = blkh_nr_item(BLOCKHEAD(LEAF));
+ ih = ITEMHEAD;
+ DEBUG_F( "nr_item = %d\n", nr_item );
+ for ( i = 0; i < nr_item; i++ )
+ {
+ if ( ih->ih_key.k_dir_id == dir_id
+ && ih->ih_key.k_objectid == objectid
+ && ih->ih_key.u.k_offset_v1.k_offset == 0
+ && ih->ih_key.u.k_offset_v1.k_uniqueness == 0 )
+ {
+
+ DEBUG_F( " depth=%d, i=%d/%d\n", depth, i, nr_item );
+
+ INFO->current_ih = ih;
+ INFO->current_item = &LEAF[ih_location(ih)];
+
+ return 1;
+ }
+
+ ih++;
+ }
+
+ DEBUG_LEAVE(FILE_ERR_BAD_FSYS);
+ errnum = FILE_ERR_BAD_FSYS;
+ return 0;
+}
+
+static int
+reiserfs_read_data( char *buf, __u32 len )
+{
+ __u32 blocksize;
+ __u32 offset;
+ __u32 to_read;
+ char *prev_buf = buf;
+
+
+ DEBUG_F( "reiserfs_read_data: INFO->file->pos=%Lu len=%u, offset=%Lu\n",
+ INFO->file->pos, len, (__u64) IH_KEY_OFFSET(INFO->current_ih) - 1 );
+
+
+ if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid
+ || IH_KEY_OFFSET( INFO->current_ih ) > INFO->file->pos + 1 )
+ {
+ search_stat( INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid );
+ goto get_next_key;
+ }
+
+ while ( errnum == 0 )
+ {
+ if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid )
+ break;
+
+ offset = INFO->file->pos - IH_KEY_OFFSET( INFO->current_ih ) + 1;
+ blocksize = ih_item_len(INFO->current_ih);
+
+
+ DEBUG_F( " loop: INFO->file->pos=%Lu len=%u, offset=%u blocksize=%u\n",
+ INFO->file->pos, len, offset, blocksize );
+
+
+ if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_DIRECT )
+ && offset < blocksize )
+ {
+ to_read = blocksize - offset;
+ if ( to_read > len )
+ to_read = len;
+
+ memcpy( buf, INFO->current_item + offset, to_read );
+ goto update_buf_len;
+ }
+ else if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_INDIRECT ) )
+ {
+ blocksize = ( blocksize >> 2 ) << INFO->blocksize_shift;
+
+ while ( offset < blocksize )
+ {
+ __u32 blocknr = le32_to_cpu(((__u32 *)
+ INFO->current_item)[offset >> INFO->blocksize_shift]);
+
+ int blk_offset = offset & (INFO->blocksize - 1);
+
+ to_read = INFO->blocksize - blk_offset;
+ if ( to_read > len )
+ to_read = len;
+
+ /* Journal is only for meta data.
+ Data blocks can be read directly without using block_read */
+ read_disk_block( INFO->file, blocknr, blk_offset, to_read,
+ buf );
+
+ update_buf_len:
+ len -= to_read;
+ buf += to_read;
+ offset += to_read;
+ INFO->file->pos += to_read;
+ if ( len == 0 )
+ goto done;
+ }
+ }
+ get_next_key:
+ next_key();
+ }
+ done:
+ return (errnum != 0) ? 0 : buf - prev_buf;
+}
+
+
+/* preconditions: reiserfs_read_super already executed, therefore
+ * INFO block is valid
+ * returns: 0 if error, nonzero iff we were able to find the file successfully
+ * postconditions: on a nonzero return, INFO->fileinfo contains the info
+ * of the file we were trying to look up, filepos is 0 and filemax is
+ * the size of the file.
+ */
+static int
+reiserfs_open_file( char *dirname )
+{
+ struct reiserfs_de_head *de_head;
+ char *rest, ch;
+ __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;
+
+ char linkbuf[PATH_MAX]; /* buffer for following symbolic links */
+ int link_count = 0;
+ int mode;
+
+ dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
+ objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
+
+ while ( 1 )
+ {
+
+ DEBUG_F( "dirname=%s\n", dirname );
+
+ /* Search for the stat info first. */
+ if ( !search_stat( dir_id, objectid ) )
+ return 0;
+
+
+ DEBUG_F( "sd_mode=0%o sd_size=%u\n",
+ sd_mode((struct stat_data *) INFO->current_item ),
+ sd_size(INFO->current_ih, INFO->current_item ));
+
+
+ mode = sd_mode((struct stat_data *)INFO->current_item);
+
+ /* If we've got a symbolic link, then chase it. */
+ if ( S_ISLNK( mode ) )
+ {
+ int len = 0;
+
+ if ( ++link_count > MAX_LINK_COUNT )
+ {
+ errnum = FILE_ERR_SYMLINK_LOOP;
+ return 0;
+ }
+
+ /* Get the symlink size. */
+ INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
+
+ /* Find out how long our remaining name is. */
+ while ( dirname[len] && !isspace( dirname[len] ) )
+ len++;
+
+ if ( INFO->file->len + len > sizeof ( linkbuf ) - 1 )
+ {
+ errnum = FILE_ERR_LENGTH;
+ return 0;
+ }
+
+ /* Copy the remaining name to the end of the symlink data. Note *
+ * that DIRNAME and LINKBUF may overlap! */
+ memmove( linkbuf + INFO->file->len, dirname, len + 1 );
+
+ INFO->fileinfo.k_dir_id = dir_id;
+ INFO->fileinfo.k_objectid = objectid;
+ INFO->file->pos = 0;
+ if ( !next_key()
+ || reiserfs_read_data( linkbuf, INFO->file->len ) != INFO->file->len )
+ return 0;
+
+
+ DEBUG_F( "symlink=%s\n", linkbuf );
+
+
+ dirname = linkbuf;
+ if ( *dirname == '/' )
+ {
+ /* It's an absolute link, so look it up in root. */
+ dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
+ objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
+ }
+ else
+ {
+ /* Relative, so look it up in our parent directory. */
+ dir_id = parent_dir_id;
+ objectid = parent_objectid;
+ }
+
+ /* Now lookup the new name. */
+ continue;
+ }
+
+ /* if we have a real file (and we're not just printing *
+ * possibilities), then this is where we want to exit */
+
+ if ( !*dirname || isspace( *dirname ) )
+ {
+ if ( !S_ISREG( mode ) )
+ {
+ errnum = FILE_ERR_BAD_TYPE;
+ return 0;
+ }
+
+ INFO->file->pos = 0;
+ INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
+
+ INFO->fileinfo.k_dir_id = dir_id;
+ INFO->fileinfo.k_objectid = objectid;
+ return next_key();
+ }
+
+ /* continue with the file/directory name interpretation */
+ while ( *dirname == '/' )
+ dirname++;
+ if ( !S_ISDIR( mode ) )
+ {
+ errnum = FILE_ERR_BAD_TYPE;
+ return 0;
+ }
+ for ( rest = dirname; ( ch = *rest ) && !isspace( ch ) && ch != '/';
+ rest++ ) ;
+ *rest = 0;
+
+ while ( 1 )
+ {
+ char *name_end;
+ int num_entries;
+
+ if ( !next_key() )
+ return 0;
+
+ if ( INFO->current_ih->ih_key.k_objectid != objectid )
+ break;
+
+ name_end = INFO->current_item + ih_item_len(INFO->current_ih);
+ de_head = ( struct reiserfs_de_head * ) INFO->current_item;
+ num_entries = ih_entry_count(INFO->current_ih);
+ while ( num_entries > 0 )
+ {
+ char *filename = INFO->current_item + deh_location(de_head);
+ char tmp = *name_end;
+
+ if( deh_state(de_head) & (1 << DEH_Visible))
+ {
+ int cmp;
+
+ /* Directory names in ReiserFS are not null * terminated.
+ * We write a temporary 0 behind it. * NOTE: that this
+ * may overwrite the first block in * the tree cache.
+ * That doesn't hurt as long as we * don't call next_key
+ * () in between. */
+ *name_end = 0;
+ cmp = strcmp( dirname, filename );
+ *name_end = tmp;
+ if ( cmp == 0 )
+ goto found;
+ }
+ /* The beginning of this name marks the end of the next name.
+ */
+ name_end = filename;
+ de_head++;
+ num_entries--;
+ }
+ }
+
+ errnum = FILE_ERR_NOTFOUND;
+ *rest = ch;
+ return 0;
+
+ found:
+ *rest = ch;
+ dirname = rest;
+
+ parent_dir_id = dir_id;
+ parent_objectid = objectid;
+ dir_id = de_head->deh_dir_id; /* LE */
+ objectid = de_head->deh_objectid; /* LE */
+ }
+}
+
+
+
+#ifndef __LITTLE_ENDIAN
+typedef union {
+ struct offset_v2 offset_v2;
+ __u64 linear;
+} offset_v2_esafe_overlay;
+
+inline __u16
+offset_v2_k_type( struct offset_v2 *v2 )
+{
+ offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
+ tmp.linear = le64_to_cpu( tmp.linear );
+ return tmp.offset_v2.k_type;
+}
+
+inline loff_t
+offset_v2_k_offset( struct offset_v2 *v2 )
+{
+ offset_v2_esafe_overlay tmp = *(offset_v2_esafe_overlay *)v2;
+ tmp.linear = le64_to_cpu( tmp.linear );
+ return tmp.offset_v2.k_offset;
+}
+#endif
+
+inline int
+uniqueness2type (__u32 uniqueness)
+{
+ switch (uniqueness) {
+ case V1_SD_UNIQUENESS: return TYPE_STAT_DATA;
+ case V1_INDIRECT_UNIQUENESS: return TYPE_INDIRECT;
+ case V1_DIRECT_UNIQUENESS: return TYPE_DIRECT;
+ case V1_DIRENTRY_UNIQUENESS: return TYPE_DIRENTRY;
+ }
+ return TYPE_ANY;
+}
--- /dev/null
+/* 256 color mode color table for Linux, partially borrowed from BootX */
+
+
+unsigned char color_table_red[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA,
+ 0x55, 0x55, 0x55, 0x55, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x02, 0x9E, 0xE9, 0xC4, 0x50, 0xC9, 0xC4, 0xE9,
+ 0x65, 0xE3, 0xC2, 0x25, 0xA4, 0xEC, 0x90, 0xA6,
+ 0xC4, 0x6A, 0xD1, 0xF3, 0x12, 0xED, 0xA0, 0xC2,
+ 0xB8, 0xD5, 0xDB, 0xD2, 0x3E, 0x16, 0xEB, 0x54,
+ 0xA9, 0xCD, 0xF5, 0x0A, 0xBA, 0xB3, 0xDC, 0x74,
+ 0xCE, 0xF6, 0xD3, 0xC5, 0xEA, 0xB8, 0xED, 0x5E,
+ 0xE5, 0x26, 0xF4, 0xA9, 0x82, 0x94, 0xE6, 0x38,
+ 0xF2, 0x0F, 0x7F, 0x49, 0xE5, 0xF4, 0xD3, 0xC3,
+ 0xC2, 0x1E, 0xD5, 0xC6, 0xA4, 0xFA, 0x0A, 0xBA,
+ 0xD4, 0xEB, 0xEA, 0xEC, 0xA8, 0xBC, 0xB4, 0xDC,
+ 0x84, 0xE4, 0xCE, 0xEC, 0x92, 0xCD, 0xDC, 0x8B,
+ 0xCC, 0x1E, 0xF6, 0xB2, 0x60, 0x2A, 0x96, 0x52,
+ 0x0F, 0xBD, 0xFA, 0xCC, 0xB8, 0x7A, 0x4C, 0xD2,
+ 0x06, 0xEF, 0x44, 0x64, 0xF4, 0xBA, 0xCE, 0xE6,
+ 0x8A, 0x6F, 0x3C, 0x70, 0x7C, 0x9C, 0xBA, 0xDF,
+ 0x2C, 0x4D, 0x3B, 0xCA, 0xDE, 0xCE, 0xEE, 0x46,
+ 0x6A, 0xAC, 0x96, 0xE5, 0x96, 0x7A, 0xBA, 0xB6,
+ 0xE2, 0x7E, 0xAA, 0xC5, 0x96, 0x9E, 0xC2, 0xAA,
+ 0xDA, 0x35, 0xB6, 0x82, 0x88, 0xBE, 0xC2, 0x9E,
+ 0xB4, 0xD5, 0xDA, 0x9C, 0xA0, 0xD0, 0xA8, 0xC7,
+ 0x72, 0xF2, 0xDB, 0x76, 0xDC, 0xBE, 0xAA, 0xF4,
+ 0x87, 0x2F, 0x53, 0x8E, 0x36, 0xCE, 0xE6, 0xCA,
+ 0xCB, 0xE4, 0xD6, 0xAA, 0x42, 0x5D, 0xB4, 0x59,
+ 0x1C, 0xC8, 0x96, 0x6C, 0xDA, 0xCE, 0xE6, 0xCB,
+ 0x96, 0x16, 0xFA, 0xBE, 0xAE, 0xFE, 0x6E, 0xD6,
+ 0xCE, 0xB6, 0xE5, 0xED, 0xDB, 0xDC, 0xF4, 0x72,
+ 0x1F, 0xAE, 0xE6, 0xC2, 0xCA, 0xC4, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+unsigned char color_table_green[] = {
+ 0x00, 0x00, 0xAA, 0xAA, 0x00, 0x00, 0xAA, 0xAA,
+ 0x55, 0x55, 0xFF, 0xFF, 0x55, 0x55, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x02, 0x88, 0xC4, 0x85, 0x44, 0xA2, 0xA8, 0xE5,
+ 0x65, 0xA6, 0xC2, 0x24, 0xA4, 0xB4, 0x62, 0x86,
+ 0x94, 0x44, 0xD2, 0xB6, 0x12, 0xD4, 0x73, 0x96,
+ 0x92, 0x95, 0xB2, 0xC2, 0x36, 0x0E, 0xBC, 0x54,
+ 0x75, 0xA5, 0xF5, 0x0A, 0xB2, 0x83, 0xC2, 0x74,
+ 0x9B, 0xBD, 0xA2, 0xCA, 0xDA, 0x8C, 0xCB, 0x42,
+ 0xAC, 0x12, 0xDA, 0x7B, 0x54, 0x94, 0xD2, 0x24,
+ 0xBE, 0x06, 0x65, 0x33, 0xBB, 0xBC, 0xAB, 0x8C,
+ 0x92, 0x1E, 0x9B, 0xB6, 0x6E, 0xFB, 0x04, 0xA2,
+ 0xC8, 0xBD, 0xAD, 0xEC, 0x92, 0xBC, 0x7B, 0x9D,
+ 0x84, 0xC4, 0xC4, 0xB4, 0x6C, 0x93, 0xA3, 0x5E,
+ 0x8D, 0x13, 0xD6, 0x82, 0x4C, 0x2A, 0x7A, 0x5A,
+ 0x0D, 0x82, 0xBB, 0xCC, 0x8B, 0x6A, 0x3C, 0xBE,
+ 0x06, 0xC4, 0x44, 0x45, 0xDB, 0x96, 0xB6, 0xDE,
+ 0x8A, 0x4D, 0x3C, 0x5A, 0x7C, 0x9C, 0xAA, 0xCB,
+ 0x1C, 0x4D, 0x2E, 0xB2, 0xBE, 0xAA, 0xDE, 0x3E,
+ 0x6A, 0xAC, 0x82, 0xE5, 0x72, 0x62, 0x92, 0x9E,
+ 0xCA, 0x4A, 0x8E, 0xBE, 0x86, 0x6B, 0xAA, 0x9A,
+ 0xBE, 0x34, 0xAB, 0x76, 0x6E, 0x9A, 0x9E, 0x62,
+ 0x76, 0xCE, 0xD3, 0x92, 0x7C, 0xB8, 0x7E, 0xC6,
+ 0x5E, 0xE2, 0xC3, 0x54, 0xAA, 0x9E, 0x8A, 0xCA,
+ 0x63, 0x2D, 0x3B, 0x8E, 0x1A, 0x9E, 0xC2, 0xA6,
+ 0xCB, 0xDC, 0xD6, 0x8E, 0x26, 0x5C, 0xB4, 0x45,
+ 0x1C, 0xB8, 0x6E, 0x4C, 0xBC, 0xAE, 0xD6, 0x92,
+ 0x63, 0x16, 0xF6, 0x8C, 0x7A, 0xFE, 0x6E, 0xBA,
+ 0xC6, 0x86, 0xAA, 0xAE, 0xDB, 0xA4, 0xD4, 0x56,
+ 0x0E, 0x6E, 0xB6, 0xB2, 0xBE, 0xBE, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+
+unsigned char color_table_blue[] = {
+ 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA,
+ 0x55, 0xFF, 0x55, 0xFF, 0x55, 0xFF, 0x55, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x04, 0x28, 0x10, 0x0B, 0x14, 0x14, 0x74, 0xC7,
+ 0x64, 0x0E, 0xC3, 0x24, 0xA4, 0x0C, 0x10, 0x20,
+ 0x0D, 0x04, 0xD1, 0x0D, 0x13, 0x22, 0x0A, 0x40,
+ 0x14, 0x0C, 0x11, 0x94, 0x0C, 0x08, 0x0B, 0x56,
+ 0x09, 0x47, 0xF4, 0x0B, 0x9C, 0x07, 0x54, 0x74,
+ 0x0F, 0x0C, 0x0F, 0xC7, 0x6C, 0x14, 0x14, 0x11,
+ 0x0B, 0x04, 0x12, 0x0C, 0x05, 0x94, 0x94, 0x0A,
+ 0x34, 0x09, 0x14, 0x08, 0x2F, 0x15, 0x19, 0x11,
+ 0x28, 0x0C, 0x0B, 0x94, 0x08, 0xFA, 0x08, 0x7C,
+ 0xBC, 0x15, 0x0A, 0xEC, 0x64, 0xBB, 0x0A, 0x0C,
+ 0x84, 0x2C, 0xA0, 0x15, 0x10, 0x0D, 0x0B, 0x0E,
+ 0x0A, 0x07, 0x10, 0x3C, 0x24, 0x2C, 0x28, 0x5C,
+ 0x0A, 0x0D, 0x0A, 0xC1, 0x22, 0x4C, 0x10, 0x94,
+ 0x04, 0x0F, 0x45, 0x08, 0x31, 0x54, 0x3C, 0xBC,
+ 0x8C, 0x09, 0x3C, 0x18, 0x7C, 0x9C, 0x7C, 0x91,
+ 0x0C, 0x4D, 0x17, 0x74, 0x0C, 0x48, 0x9C, 0x3C,
+ 0x6A, 0xAC, 0x5C, 0xE3, 0x29, 0x3C, 0x2C, 0x7C,
+ 0x6C, 0x04, 0x14, 0xA9, 0x74, 0x07, 0x2C, 0x74,
+ 0x4C, 0x34, 0x97, 0x5C, 0x38, 0x0C, 0x5C, 0x04,
+ 0x0C, 0xBA, 0xBC, 0x78, 0x18, 0x88, 0x24, 0xC2,
+ 0x3C, 0xB4, 0x87, 0x0C, 0x14, 0x4C, 0x3C, 0x10,
+ 0x17, 0x2C, 0x0A, 0x8C, 0x04, 0x1C, 0x44, 0x2C,
+ 0xCD, 0xD8, 0xD4, 0x34, 0x0C, 0x5B, 0xB4, 0x1E,
+ 0x1D, 0xAC, 0x24, 0x18, 0x20, 0x5C, 0xB4, 0x1C,
+ 0x09, 0x14, 0xFC, 0x0C, 0x10, 0xFC, 0x6C, 0x7C,
+ 0xB4, 0x1C, 0x15, 0x17, 0xDB, 0x18, 0x21, 0x24,
+ 0x04, 0x04, 0x44, 0x8C, 0x8C, 0xB7, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
--- /dev/null
+/* effects.c */
+/* Adds splash screen and status bar effects for graphical yaboot */
+
+#include "file.h"
+#include "yaboot.h"
+#include "stdlib.h"
+
+#define SB_XSTART 170
+#define SB_XEND 472
+#define SB_YSTART 402
+
+unsigned char bar_grad[] = { 228, 237, 246, 254, 207, 254, 246, 237, 228, 206 };
+
+int scrOpen(void);
+void scrSetEntireColorMap(unsigned char *);
+void scrClear(unsigned char);
+void pcxDisplay(unsigned char *, unsigned int);
+void scrFadeColorMap(unsigned char *, unsigned char *, int);
+unsigned char *pcxColormap(unsigned char *, int);
+void scrPutPixel(int, int, unsigned char);
+
+void fxDisplaySplash(struct boot_fspec_t *filespec)
+{
+ void *gfx_file;
+ int gfx_len;
+ unsigned char *grey_map;
+ int start_time;
+ struct boot_file_t file;
+ int result;
+ static int been_here = 0;
+
+ if(!been_here)
+ {
+ been_here = 1;
+ gfx_file = (void *) malloc(1024 * 512);
+ if (gfx_file == NULL) {
+ prom_printf("malloc failed in fxDisplaySplash()\n");
+ return;
+ }
+
+ scrOpen();
+
+ result = open_file(filespec, &file);
+
+ if(result != FILE_ERR_OK)
+ {
+ prom_printf("Error loading splash screen\n");
+ return;
+ }
+
+ gfx_len = file.fs->read(&file, 1024 * 512 - 765, gfx_file);
+ file.fs->close(&file);
+ grey_map = gfx_file + gfx_len;
+ memset(grey_map, 0/*128*/, 765);
+ }
+
+ scrSetEntireColorMap(grey_map);
+ scrClear(0);
+
+ start_time = prom_getms();
+ while(prom_getms() < start_time + 2000);
+
+ pcxDisplay(gfx_file, gfx_len);
+ scrFadeColorMap(grey_map, pcxColormap( gfx_file, gfx_len ), 2);
+}
+
+
+void fxUpdateSB(unsigned number, unsigned total)
+{
+ int x, y;
+
+ for(x = SB_XSTART; x < SB_XSTART + (SB_XEND - SB_XSTART) * number / total; ++x)
+ {
+ for(y = 0; y < 10; ++y)
+ scrPutPixel(x, SB_YSTART + y, bar_grad[y]);
+ }
+}
+
+
+#define BLOCK_INDEX (1024 * 64)
+
+int fxReadImage(struct boot_file_t *file, unsigned int filesize, void *base)
+{
+ unsigned int count, result = 0;
+
+ for(count = 0; count < filesize; count += result)
+ {
+ result = ((filesize - count) < BLOCK_INDEX) ? (filesize - count) : BLOCK_INDEX;
+ if ((result = file->fs->read(file, result, base + count)) != BLOCK_INDEX)
+ break;
+ fxUpdateSB(count + result, filesize);
+ }
+ fxUpdateSB(count + result, filesize);
+ return(count + result);
+}
--- /dev/null
+/* Crude PCX file loading and display for 640x480 image at boot */
+
+unsigned char *pcxColormap(unsigned char *gfx_file, int gfx_len)
+{
+ return(gfx_file + gfx_len - 768);
+}
+
+extern void scrPutPixel( int x, int y, unsigned char c );
+
+static void inline do_putpixel(int offset, unsigned char c)
+{
+ scrPutPixel(offset % 640, offset / 640, c);
+}
+
+void pcxDisplay(unsigned char *gfx_file, unsigned gfx_len)
+{
+ int offset, file_offset, i, c, f;
+
+ for(offset = 0, file_offset = 128; offset < 640 * 480 && file_offset < gfx_len - 769; file_offset++)
+ {
+ if(((c = gfx_file[file_offset]) & 0xc0) == 0xc0)
+ {
+ f = gfx_file[++file_offset];
+ c &= 0x3f;
+ for(i = 0; i < c; ++i)
+ do_putpixel(offset++, f);
+ }
+ else
+ do_putpixel(offset++, c);
+ }
+}
--- /dev/null
+#include "prom.h"
+
+#define WINDOW_X_SIZE 640
+#define WINDOW_Y_SIZE 480
+
+
+static prom_handle videodev;
+static prom_handle videop;
+static int Xres, Yres;
+static int Xstart, Ystart;
+static int rowbytes;
+static int zoom;
+static unsigned char *address;
+
+static int scrSetColorMap( unsigned char color,
+ unsigned char r, unsigned char g, unsigned char b );
+
+
+int scrOpen()
+{
+ int result = 0;
+
+ videodev = (prom_handle)call_prom( "open", 1, 1, "screen" );
+ if( videodev == PROM_INVALID_HANDLE )
+ return(-1);
+ videop = (prom_handle)call_prom( "instance-to-package", 1, 1, videodev );
+ if( videop == PROM_INVALID_HANDLE )
+ return(-1);
+
+ result |= prom_getprop(videop, "width", &Xres, 4 );
+ result |= prom_getprop(videop, "height", &Yres, 4 );
+ result |= prom_getprop(videop, "address", &address, 4 );
+ result |= prom_getprop(videop, "linebytes", &rowbytes, 4 );
+
+ prom_map (address, address, rowbytes * Xres);
+
+#if DEBUG
+ prom_printf("width : %d\n", Xres);
+ prom_printf("height : %d\n", Yres);
+ prom_printf("address : 0x%08lx\n", address);
+ prom_printf("linebytes : %d\n", rowbytes);
+ prom_printf("result : %d\n", result);
+#endif
+
+ if( result < 0 )
+ return( -1 );
+
+ zoom = Xres / WINDOW_X_SIZE > Yres / WINDOW_Y_SIZE ? Yres / WINDOW_Y_SIZE : Xres / WINDOW_X_SIZE;
+
+ Xstart = Xres / 2 - WINDOW_X_SIZE / 2 * zoom;
+ Ystart = Yres / 2 - WINDOW_Y_SIZE / 2 * zoom;
+
+#if DEBUG
+ prom_printf("zoom : %d\n", zoom);
+ prom_printf("Xstart : %d\n", Xstart);
+ prom_printf("Ystart : %d\n", Ystart);
+#endif
+
+ return( 0 );
+}
+
+
+void scrClear( unsigned char c )
+{
+ int x, y;
+
+ for (y = 0; y < Yres; y++)
+ for (x = 0; x < Xres; x++)
+ address[y * rowbytes + x] = c;
+}
+
+
+void scrClose()
+{
+ call_prom( "close", 1, 0, videodev );
+ videodev = 0;
+}
+
+
+void scrReset()
+{
+ int c;
+ extern unsigned char color_table_red[],
+ color_table_green[],
+ color_table_blue[];
+
+ for( c = 0; c < 16; ++c )
+ scrSetColorMap( c, color_table_red[c],
+ color_table_green[c],
+ color_table_blue[c] );
+// scrClose();
+}
+
+static void inline do_pix( int x, int y, unsigned char c )
+{
+ address[ y * rowbytes + x ] = c;
+}
+
+
+void scrPutPixel( int x, int y, unsigned char c )
+{
+ int zx, zy;
+
+ for( zy = 0; zy < zoom; ++zy )
+ for( zx = 0; zx < zoom; ++zx )
+ do_pix( x * zoom + zx + Xstart, y * zoom + zy + Ystart, c );
+}
+
+
+int scrSetColorMap( unsigned char color, unsigned char r, unsigned char g, unsigned char b )
+{
+ int result;
+
+ result = (int)call_prom( "call-method", 6, 1, "color!", videodev, color, b, g, r );
+
+ return( result );
+}
+
+
+void scrFillColorMap( unsigned char r, unsigned char g, unsigned char b )
+{
+ int c;
+
+ for( c = 0; c < 256; ++c )
+ scrSetColorMap( c, r, g, b );
+}
+
+
+void scrSetEntireColorMap( unsigned char *map )
+{
+ int c;
+
+ for( c = 0; c < 256; ++c )
+ scrSetColorMap( c, map[c * 3], map[c * 3 + 1], map[c * 3 + 2] );
+}
+
+
+void scrFadeColorMap( unsigned char *first, unsigned char *last, int rate )
+{
+ int inc, c;
+
+ for( inc = 0; inc < 256; inc += rate )
+ for( c = 0; c < 256; ++c )
+ scrSetColorMap( c, first[c * 3 + 0] * (255 - inc) / 255 + last[c * 3 + 0] * inc / 255,
+ first[c * 3 + 1] * (255 - inc) / 255 + last[c * 3 + 1] * inc / 255,
+ first[c * 3 + 2] * (255 - inc) / 255 + last[c * 3 + 2] * inc / 255 );
+}
--- /dev/null
+/*
+ * linux/fs/isofs/util.c
+ *
+ * The special functions in the file are numbered according to the section
+ * of the iso 9660 standard in which they are described. isonum_733 will
+ * convert numbers according to section 7.3.3, etc.
+ *
+ * isofs special functions. This file was lifted in its entirety from
+ * the 386BSD iso9660 filesystem, by Pace Willisson <pace@blitz.com>.
+ */
+
+int
+isonum_711 (char * p)
+{
+ return (*p & 0xff);
+}
+
+int
+isonum_712 (char * p)
+{
+ int val;
+
+ val = *p;
+ if (val & 0x80)
+ val |= 0xffffff00;
+ return (val);
+}
+
+int
+isonum_721 (char * p)
+{
+ return ((p[0] & 0xff) | ((p[1] & 0xff) << 8));
+}
+
+int
+isonum_722 (char * p)
+{
+ return (((p[0] & 0xff) << 8) | (p[1] & 0xff));
+}
+
+int
+isonum_723 (char * p)
+{
+#if 0
+ if (p[0] != p[3] || p[1] != p[2]) {
+ fprintf (stderr, "invalid format 7.2.3 number\n");
+ exit (1);
+ }
+#endif
+ return (isonum_721 (p));
+}
+
+int
+isonum_731 (char * p)
+{
+ return ((p[0] & 0xff)
+ | ((p[1] & 0xff) << 8)
+ | ((p[2] & 0xff) << 16)
+ | ((p[3] & 0xff) << 24));
+}
+
+int
+isonum_732 (char * p)
+{
+ return (((p[0] & 0xff) << 24)
+ | ((p[1] & 0xff) << 16)
+ | ((p[2] & 0xff) << 8)
+ | (p[3] & 0xff));
+}
+
+int
+isonum_733 (char * p)
+{
+#if 0
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (p[i] != p[7-i]) {
+ fprintf (stderr, "bad format 7.3.3 number\n");
+ exit (1);
+ }
+ }
+#endif
+ return (isonum_731 (p));
+}
+
--- /dev/null
+/* md5.c - an implementation of the MD5 algorithm and MD5 crypt */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2000 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* See RFC 1321 for a description of the MD5 algorithm.
+ */
+
+#include "string.h"
+#include "md5.h"
+
+#ifdef TEST
+# include <stdio.h>
+# define USE_MD5_PASSWORDS
+# define USE_MD5
+#endif
+
+#ifdef USE_MD5_PASSWORDS
+# define USE_MD5
+#endif
+
+#ifdef USE_MD5
+#define cpu_to_le32(x) le32_to_cpu((x))
+unsigned long le32_to_cpu(unsigned long x)
+{
+ return (((x & 0x000000ffU) << 24) |
+ ((x & 0x0000ff00U) << 8) |
+ ((x & 0x00ff0000U) >> 8) |
+ ((x & 0xff000000U) >> 24));
+}
+
+typedef unsigned int UINT4;
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x >> (32 - (n)))))
+
+static UINT4 initstate[4] =
+{
+ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
+};
+
+static char s1[4] = { 7, 12, 17, 22 };
+static char s2[4] = { 5, 9, 14, 20 };
+static char s3[4] = { 4, 11, 16, 23 };
+static char s4[4] = { 6, 10, 15, 21 };
+
+static UINT4 T[64] =
+{
+ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+ 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+};
+
+static const char *b64t =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static UINT4 state[4];
+static unsigned int length;
+static unsigned char buffer[64];
+
+static void
+md5_transform (const unsigned char block[64])
+{
+ int i, j;
+ UINT4 a,b,c,d,tmp;
+ const UINT4 *x = (UINT4 *) block;
+
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+
+ /* Round 1 */
+ for (i = 0; i < 16; i++)
+ {
+ tmp = a + F (b, c, d) + le32_to_cpu (x[i]) + T[i];
+ tmp = ROTATE_LEFT (tmp, s1[i & 3]);
+ tmp += b;
+ a = d; d = c; c = b; b = tmp;
+ }
+ /* Round 2 */
+ for (i = 0, j = 1; i < 16; i++, j += 5)
+ {
+ tmp = a + G (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+16];
+ tmp = ROTATE_LEFT (tmp, s2[i & 3]);
+ tmp += b;
+ a = d; d = c; c = b; b = tmp;
+ }
+ /* Round 3 */
+ for (i = 0, j = 5; i < 16; i++, j += 3)
+ {
+ tmp = a + H (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+32];
+ tmp = ROTATE_LEFT (tmp, s3[i & 3]);
+ tmp += b;
+ a = d; d = c; c = b; b = tmp;
+ }
+ /* Round 4 */
+ for (i = 0, j = 0; i < 16; i++, j += 7)
+ {
+ tmp = a + I (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+48];
+ tmp = ROTATE_LEFT (tmp, s4[i & 3]);
+ tmp += b;
+ a = d; d = c; c = b; b = tmp;
+ }
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+}
+
+static void
+md5_init(void)
+{
+ memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+ length = 0;
+}
+
+static void
+md5_update (const char *input, int inputlen)
+{
+ int buflen = length & 63;
+ length += inputlen;
+ if (buflen + inputlen < 64)
+ {
+ memcpy (buffer + buflen, input, inputlen);
+ buflen += inputlen;
+ return;
+ }
+
+ memcpy (buffer + buflen, input, 64 - buflen);
+ md5_transform (buffer);
+ input += 64 - buflen;
+ inputlen -= 64 - buflen;
+ while (inputlen >= 64)
+ {
+ md5_transform (input);
+ input += 64;
+ inputlen -= 64;
+ }
+ memcpy (buffer, input, inputlen);
+ buflen = inputlen;
+}
+
+static unsigned char *
+md5_final()
+{
+ int i, buflen = length & 63;
+
+ buffer[buflen++] = 0x80;
+ memset (buffer+buflen, 0, 64 - buflen);
+ if (buflen > 56)
+ {
+ md5_transform (buffer);
+ memset (buffer, 0, 64);
+ buflen = 0;
+ }
+
+ *(UINT4 *) (buffer + 56) = cpu_to_le32 (8 * length);
+ *(UINT4 *) (buffer + 60) = 0;
+ md5_transform (buffer);
+
+ for (i = 0; i < 4; i++)
+ state[i] = cpu_to_le32 (state[i]);
+ return (unsigned char *) state;
+}
+
+#ifdef USE_MD5_PASSWORDS
+/* If CHECK is true, check a password for correctness. Returns 0
+ if password was correct, and a value != 0 for error, similarly
+ to strcmp.
+ If CHECK is false, crypt KEY and save the result in CRYPTED.
+ CRYPTED must have a salt. */
+int
+md5_password (const char *key, char *crypted, int check)
+{
+ int keylen = strlen (key);
+ char *salt = crypted + 3; /* skip $1$ header */
+ char *p;
+ int saltlen;
+ int i, n;
+ unsigned char alt_result[16];
+ unsigned char *digest;
+
+ if (check)
+ saltlen = strstr (salt, "$") - salt;
+ else
+ {
+ char *end = strstr (salt, "$");
+ if (end && end - salt < 8)
+ saltlen = end - salt;
+ else
+ saltlen = 8;
+
+ salt[saltlen] = '$';
+ }
+
+ md5_init ();
+ md5_update (key, keylen);
+ md5_update (salt, saltlen);
+ md5_update (key, keylen);
+ digest = md5_final ();
+ memcpy (alt_result, digest, 16);
+
+ memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+ length = 0;
+ md5_update (key, keylen);
+ md5_update (crypted, 3 + saltlen); /* include the $1$ header */
+ for (i = keylen; i > 16; i -= 16)
+ md5_update (alt_result, 16);
+ md5_update (alt_result, i);
+
+ for (i = keylen; i > 0; i >>= 1)
+ md5_update (key + ((i & 1) ? keylen : 0), 1);
+ digest = md5_final ();
+
+ for (i = 0; i < 1000; i++)
+ {
+ memcpy (alt_result, digest, 16);
+
+ memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+ length = 0;
+ if ((i & 1) != 0)
+ md5_update (key, keylen);
+ else
+ md5_update (alt_result, 16);
+
+ if (i % 3 != 0)
+ md5_update (salt, saltlen);
+
+ if (i % 7 != 0)
+ md5_update (key, keylen);
+
+ if ((i & 1) != 0)
+ md5_update (alt_result, 16);
+ else
+ md5_update (key, keylen);
+ digest = md5_final ();
+ }
+
+ p = salt + saltlen + 1;
+ for (i = 0; i < 5; i++)
+ {
+ unsigned int w =
+ digest[i == 4 ? 5 : 12+i] | (digest[6+i] << 8) | (digest[i] << 16);
+ for (n = 4; n-- > 0;)
+ {
+ if (check)
+ {
+ if (*p++ != b64t[w & 0x3f])
+ return 1;
+ }
+ else
+ {
+ *p++ = b64t[w & 0x3f];
+ }
+
+ w >>= 6;
+ }
+ }
+ {
+ unsigned int w = digest[11];
+ for (n = 2; n-- > 0;)
+ {
+ if (check)
+ {
+ if (*p++ != b64t[w & 0x3f])
+ return 1;
+ }
+ else
+ {
+ *p++ = b64t[w & 0x3f];
+ }
+
+ w >>= 6;
+ }
+ }
+
+ if (! check)
+ *p = '\0';
+
+ return *p;
+}
+#endif
+
+#ifdef TEST
+static char *
+md5 (const char *input)
+{
+ memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+ length = 0;
+ md5_update (input, strlen (input));
+ return md5_final ();
+}
+
+static void
+test (char *buffer, char *expected)
+{
+ char result[16 * 3 +1];
+ unsigned char* digest = md5 (buffer);
+ int i;
+
+ for (i=0; i < 16; i++)
+ sprintf (result+2*i, "%02x", digest[i]);
+
+ if (strcmp (result, expected))
+ printf ("MD5(%s) failed: %s\n", buffer, result);
+ else
+ printf ("MD5(%s) OK\n", buffer);
+}
+
+int
+main (void)
+{
+ test ("", "d41d8cd98f00b204e9800998ecf8427e");
+ test ("a", "0cc175b9c0f1b6a831c399e269772661");
+ test ("abc", "900150983cd24fb0d6963f7d28e17f72");
+ test ("message digest", "f96b697d7cb7938d525a2f31aaf161d0");
+ test ("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
+ test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "d174ab98d277d9f5a5611c2c9f419d9f");
+ test ("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ "57edf4a22be3c955ac49da2e2107b67a");
+ test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz3456",
+ "6831fa90115bb9a54fbcd4f9fee0b5c4");
+ test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz345",
+ "bc40505cc94a43b7ff3e2ac027325233");
+ test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz34567",
+ "fa94b73a6f072a0239b52acacfbcf9fa");
+ test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz345678901234",
+ "bd201eae17f29568927414fa326f1267");
+ test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz34567890123",
+ "80063db1e6b70a2e91eac903f0e46b85");
+
+ if (check_md5_password ("Hello world!",
+ "$1$saltstri$YMyguxXMBpd2TEZ.vS/3q1"))
+ printf ("Password differs\n");
+ else
+ printf ("Password OK\n");
+ return 0;
+}
+#endif
+
+#endif
--- /dev/null
+/* File related stuff
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+
+ Todo: Add disklabel (or let OF do it ?). Eventually think about
+ fixing CDROM handling by directly using the ATAPI layer.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "ctype.h"
+#include "types.h"
+#include "stddef.h"
+#include "stdlib.h"
+#include "mac-part.h"
+#include "fdisk-part.h"
+#include "partition.h"
+#include "prom.h"
+#include "string.h"
+#include "linux/iso_fs.h"
+
+/* We currently don't check the partition type, some users
+ * are putting crap there and still expect it to work...
+ */
+#undef CHECK_FOR_VALID_MAC_PARTITION_TYPE
+
+#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
+static const char *valid_mac_partition_types[] = {
+ "apple_unix_svr2",
+ "linux",
+ "apple_hfs",
+ "apple_boot",
+ "apple_bootstrap",
+ NULL
+};
+#endif
+
+
+/* Local functions */
+static unsigned long swab32(unsigned long value);
+
+#define MAX_BLOCK_SIZE 2048
+static unsigned char block_buffer[MAX_BLOCK_SIZE];
+
+static void
+add_new_partition( struct partition_t** list, int part_number,
+ unsigned long part_start, unsigned long part_size,
+ unsigned short part_blocksize )
+{
+ struct partition_t* part;
+ part = (struct partition_t*)malloc(sizeof(struct partition_t));
+
+ part->part_number = part_number;
+ part->part_start = part_start;
+ part->part_size = part_size;
+ part->blocksize = part_blocksize;
+
+ /* Tack this entry onto the list */
+ part->next = *list;
+ *list = part;
+}
+
+/* Note, we rely on partitions being dev-block-size aligned,
+ * I have to check if it's true. If it's not, then things will get
+ * a bit more complicated
+ */
+static void
+partition_mac_lookup( const char *dev_name, prom_handle disk,
+ unsigned int prom_blksize, struct partition_t** list )
+{
+ int block, map_size;
+
+ /* block_buffer contains block 0 from the partitions_lookup() stage */
+ struct mac_partition* part = (struct mac_partition *)block_buffer;
+ unsigned short ptable_block_size =
+ ((struct mac_driver_desc *)block_buffer)->block_size;
+
+ map_size = 1;
+ for (block=1; block < map_size + 1; block++)
+ {
+#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
+ int valid = 0;
+ const char *ptype;
+#endif
+ if (prom_readblocks(disk, block, 1, block_buffer) != 1) {
+ prom_printf("Can't read partition %d\n", block);
+ break;
+ }
+ if (part->signature != MAC_PARTITION_MAGIC) {
+#if 0
+ prom_printf("Wrong partition %d signature\n", block);
+#endif
+ break;
+ }
+ if (block == 1)
+ map_size = part->map_count;
+
+#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
+ /* We don't bother looking at swap partitions of any type,
+ * and the rest are the ones we know about */
+ for (ptype = valid_mac_partition_types; ptype; ptype++)
+ if (!strcmp (part->type, ptype))
+ {
+ valid = 1;
+ break;
+ }
+#if DEBUG
+ if (!valid)
+ prom_printf( "MAC: Unsupported partition #%d; type=%s\n",
+ block, part->type );
+#endif
+#endif
+
+
+#ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
+ if (valid)
+#endif
+ /* We use the partition block size from the partition table.
+ * The filesystem implmentations are responsible for mapping
+ * to their own fs blocksize */
+ add_new_partition(
+ list, /* partition list */
+ block, /* partition number */
+ part->start_block + part->data_start, /* start */
+ part->data_count, /* size */
+ ptable_block_size );
+ }
+}
+
+/*
+ * Same function as partition_mac_lookup(), except for fdisk
+ * partitioned disks.
+ */
+static void
+partition_fdisk_lookup( const char *dev_name, prom_handle disk,
+ unsigned int prom_blksize, struct partition_t** list )
+{
+ int partition;
+
+ /* fdisk partition tables start at offset 0x1be
+ * from byte 0 of the boot drive.
+ */
+ struct fdisk_partition* part =
+ (struct fdisk_partition *) (block_buffer + 0x1be);
+
+ for (partition=1; partition <= 4 ;partition++, part++) {
+ if (part->sys_ind == LINUX_NATIVE) {
+ add_new_partition( list,
+ partition,
+ swab32(*(unsigned int *)(part->start4)),
+ swab32(*(unsigned int *)(part->size4)),
+ 512 /*blksize*/ );
+ }
+ }
+}
+
+/* I don't know if it's possible to handle multisession and other multitrack
+ * stuffs with the current OF disklabel package. This can still be implemented
+ * with direct calls to atapi stuffs.
+ * Currently, we enter this code for any device of block size 0x2048 who lacks
+ * a MacOS partition map signature.
+ */
+static int
+identify_iso_fs(ihandle device, unsigned int *iso_root_block)
+{
+ int block;
+
+ for (block = 16; block < 100; block++) {
+ struct iso_volume_descriptor * vdp;
+
+ if (prom_readblocks(device, block, 1, block_buffer) != 1) {
+ prom_printf("Can't read volume desc block %d\n", block);
+ break;
+ }
+
+ vdp = (struct iso_volume_descriptor *)block_buffer;
+
+ /* Due to the overlapping physical location of the descriptors,
+ * ISO CDs can match hdp->id==HS_STANDARD_ID as well. To ensure
+ * proper identification in this case, we first check for ISO.
+ */
+ if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
+ *iso_root_block = block;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+struct partition_t*
+partitions_lookup(const char *device)
+{
+ ihandle disk;
+ struct mac_driver_desc *desc = (struct mac_driver_desc *)block_buffer;
+ struct partition_t* list = NULL;
+ unsigned int prom_blksize, iso_root_block;
+
+ strncpy(block_buffer, device, 2040);
+ strcat(block_buffer, ":0");
+
+ /* Open device */
+ disk = prom_open(block_buffer);
+ if (disk == NULL) {
+ prom_printf("Can't open device <%s>\n", block_buffer);
+ goto bail;
+ }
+ prom_blksize = prom_getblksize(disk);
+#if DEBUG
+ prom_printf("block size of device is %d\n", prom_blksize);
+#endif
+ if (prom_blksize <= 1)
+ prom_blksize = 512;
+ if (prom_blksize > MAX_BLOCK_SIZE) {
+ prom_printf("block_size %d not supported !\n");
+ goto bail;
+ }
+
+ /* Read boot blocs */
+ if (prom_readblocks(disk, 0, 1, block_buffer) != 1) {
+ prom_printf("Can't read boot blocs\n");
+ goto bail;
+ }
+ if (desc->signature == MAC_DRIVER_MAGIC) {
+ /* pdisk partition format */
+ partition_mac_lookup(device, disk, prom_blksize, &list);
+ } else if ((block_buffer[510] == 0x55) && (block_buffer[511] == 0xaa)) {
+ /* fdisk partition format */
+ partition_fdisk_lookup(device, disk, prom_blksize, &list);
+ } else if (prom_blksize == 2048 && identify_iso_fs(disk, &iso_root_block)) {
+ add_new_partition( &list,
+ 0,
+ iso_root_block,
+ 0,
+ prom_blksize);
+ prom_printf("ISO9660 disk\n");
+ } else {
+ prom_printf("Not a macintosh-formatted disk !\n");
+ goto bail;
+ }
+
+bail:
+ prom_close(disk);
+
+ return list;
+}
+
+/* Freed in reverse order of allocation to help malloc'ator */
+void
+partitions_free(struct partition_t* list)
+{
+ struct partition_t* next;
+
+ while(list) {
+ next = list->next;
+ free(list);
+ list = next;
+ }
+}
+unsigned long
+swab32(unsigned long value)
+{
+ __u32 result;
+
+ __asm__("rlwimi %0,%1,24,16,23\n\t"
+ "rlwimi %0,%1,8,8,15\n\t"
+ "rlwimi %0,%1,24,0,7"
+ : "=r" (result)
+ : "r" (value), "0" (value >> 24));
+ return result;
+}
+
+
--- /dev/null
+/*
+ Routines for talking to the Open Firmware PROM on
+ Power Macintosh computers.
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+ Copyright (C) 1999 Marius Vollmer
+ Copyright (C) 1996 Paul Mackerras.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ */
+
+#include "prom.h"
+#include "stdarg.h"
+#include "stddef.h"
+#include "stdlib.h"
+#include "types.h"
+#include "ctype.h"
+#include "asm/processor.h"
+
+#define READ_BLOCKS_USE_READ 1
+
+prom_entry prom;
+
+ihandle prom_stdin, prom_stdout;
+
+//extern int vsprintf(char *buf, const char *fmt, va_list args);
+
+static ihandle prom_mem, prom_mmu;
+static ihandle prom_chosen, prom_options;
+
+struct prom_args {
+ const char *service;
+ int nargs;
+ int nret;
+ void *args[10];
+};
+
+void *
+call_prom (const char *service, int nargs, int nret, ...)
+{
+ va_list list;
+ int i;
+ struct prom_args prom_args;
+
+ prom_args.service = service;
+ prom_args.nargs = nargs;
+ prom_args.nret = nret;
+ va_start (list, nret);
+ for (i = 0; i < nargs; ++i)
+ prom_args.args[i] = va_arg(list, void *);
+ va_end(list);
+ for (i = 0; i < nret; ++i)
+ prom_args.args[i + nargs] = 0;
+ prom (&prom_args);
+ if (nret > 0)
+ return prom_args.args[nargs];
+ else
+ return 0;
+}
+
+void *
+call_prom_return (const char *service, int nargs, int nret, ...)
+{
+ va_list list;
+ int i;
+ void* result;
+ struct prom_args prom_args;
+
+ prom_args.service = service;
+ prom_args.nargs = nargs;
+ prom_args.nret = nret;
+ va_start (list, nret);
+ for (i = 0; i < nargs; ++i)
+ prom_args.args[i] = va_arg(list, void *);
+ for (i = 0; i < nret; ++i)
+ prom_args.args[i + nargs] = 0;
+ if (prom (&prom_args) != 0)
+ return PROM_INVALID_HANDLE;
+ if (nret > 0) {
+ result = prom_args.args[nargs];
+ for (i=1; i<nret; i++) {
+ void** rp = va_arg(list, void**);
+ *rp = prom_args.args[i+nargs];
+ }
+ } else
+ result = 0;
+ va_end(list);
+ return result;
+}
+
+static void *
+call_method_1 (char *method, prom_handle h, int nargs, ...)
+{
+ va_list list;
+ int i;
+ struct prom_args prom_args;
+
+ prom_args.service = "call-method";
+ prom_args.nargs = nargs+2;
+ prom_args.nret = 2;
+ prom_args.args[0] = method;
+ prom_args.args[1] = h;
+ va_start (list, nargs);
+ for (i = 0; i < nargs; ++i)
+ prom_args.args[2+i] = va_arg(list, void *);
+ va_end(list);
+ prom_args.args[2+nargs] = 0;
+ prom_args.args[2+nargs+1] = 0;
+
+ prom (&prom_args);
+
+ if (prom_args.args[2+nargs] != 0)
+ {
+ prom_printf ("method '%s' failed %d\n", method, prom_args.args[2+nargs]);
+ return 0;
+ }
+ return prom_args.args[2+nargs+1];
+}
+
+
+prom_handle
+prom_finddevice (char *name)
+{
+ return call_prom ("finddevice", 1, 1, name);
+}
+
+prom_handle
+prom_findpackage(char *path)
+{
+ return call_prom ("find-package", 1, 1, path);
+}
+
+int
+prom_getprop (prom_handle pack, char *name, void *mem, int len)
+{
+ return (int)call_prom ("getprop", 4, 1, pack, name, mem, len);
+}
+
+int
+prom_get_chosen (char *name, void *mem, int len)
+{
+ return prom_getprop (prom_chosen, name, mem, len);
+}
+
+int
+prom_get_options (char *name, void *mem, int len)
+{
+ if (prom_options == (void *)-1)
+ return -1;
+ return prom_getprop (prom_options, name, mem, len);
+}
+
+void
+prom_init (prom_entry pp)
+{
+ prom = pp;
+
+ prom_chosen = prom_finddevice ("/chosen");
+ if (prom_chosen == (void *)-1)
+ prom_exit ();
+ prom_options = prom_finddevice ("/options");
+ if (prom_get_chosen ("stdout", &prom_stdout, sizeof(prom_stdout)) <= 0)
+ prom_exit();
+ if (prom_get_chosen ("stdin", &prom_stdin, sizeof(prom_stdin)) <= 0)
+ prom_abort ("\nCan't open stdin");
+ if (prom_get_chosen ("memory", &prom_mem, sizeof(prom_mem)) <= 0)
+ prom_abort ("\nCan't get mem handle");
+ if (prom_get_chosen ("mmu", &prom_mmu, sizeof(prom_mmu)) <= 0)
+ prom_abort ("\nCan't get mmu handle");
+
+ // move cursor to fresh line
+ prom_printf ("\n");
+
+ /* Add a few OF methods (thanks Darwin) */
+#if DEBUG
+ prom_printf ("Adding OF methods...\n");
+#endif
+
+ prom_interpret (
+ /* All values in this forth code are in hex */
+ "hex "
+ /* Those are a few utilities ripped from Apple */
+ ": D2NIP decode-int nip nip ;\r" // A useful function to save space
+ ": GPP$ get-package-property 0= ;\r" // Another useful function to save space
+ ": ^on0 0= if -1 throw then ;\r" // Bail if result zero
+ ": $CM $call-method ;\r"
+ );
+
+ /* Some forth words used by the release method */
+ prom_interpret (
+ " \" /chosen\" find-package if "
+ "dup \" memory\" rot GPP$ if "
+ "D2NIP swap " // ( MEMORY-ihandle "/chosen"-phandle )
+ "\" mmu\" rot GPP$ if "
+ "D2NIP " // ( MEMORY-ihandle MMU-ihandle )
+ "else "
+ "0 " // ( MEMORY-ihandle 0 )
+ "then "
+ "else "
+ "0 0 " // ( 0 0 )
+ "then "
+ "else "
+ "0 0 " // ( 0 0 )
+ "then\r"
+ "value mmu# "
+ "value mem# "
+ );
+
+ prom_interpret (
+ ": ^mem mem# $CM ; "
+ ": ^mmu mmu# $CM ; "
+ );
+
+#if DEBUG
+ prom_printf ("OF interface initialized.\n");
+#endif
+}
+
+prom_handle
+prom_open (char *spec)
+{
+ return call_prom ("open", 1, 1, spec, strlen(spec));
+}
+
+void
+prom_close (prom_handle file)
+{
+ call_prom ("close", 1, 0, file);
+}
+
+int
+prom_read (prom_handle file, void *buf, int n)
+{
+ int result = 0;
+ int retries = 10;
+
+ if (n == 0)
+ return 0;
+ while(--retries) {
+ result = (int)call_prom ("read", 3, 1, file, buf, n);
+ if (result != 0)
+ break;
+ call_prom("interpret", 1, 1, " 10 ms");
+ }
+
+ return result;
+}
+
+int
+prom_write (prom_handle file, void *buf, int n)
+{
+ return (int)call_prom ("write", 3, 1, file, buf, n);
+}
+
+int
+prom_seek (prom_handle file, int pos)
+{
+ int status = (int)call_prom ("seek", 3, 1, file, 0, pos);
+ return status == 0 || status == 1;
+}
+
+int
+prom_lseek (prom_handle file, unsigned long long pos)
+{
+ int status = (int)call_prom ("seek", 3, 1, file,
+ (unsigned int)(pos >> 32), (unsigned int)(pos & 0xffffffffUL));
+ return status == 0 || status == 1;
+}
+
+int
+prom_loadmethod (prom_handle device, void* addr)
+{
+ return (int)call_method_1 ("load", device, 1, addr);
+}
+
+int
+prom_getblksize (prom_handle file)
+{
+ return (int)call_method_1 ("block-size", file, 0);
+}
+
+int
+prom_readblocks (prom_handle dev, int blockNum, int blockCount, void *buffer)
+{
+#if READ_BLOCKS_USE_READ
+ int status;
+ unsigned int blksize;
+
+ blksize = prom_getblksize(dev);
+ if (blksize <= 1)
+ blksize = 512;
+ status = prom_seek(dev, blockNum * blksize);
+ if (status != 1) {
+ return 0;
+ prom_printf("Can't seek to 0x%x\n", blockNum * blksize);
+ }
+
+ status = prom_read(dev, buffer, blockCount * blksize);
+// prom_printf("prom_readblocks, bl: %d, cnt: %d, status: %d\n",
+// blockNum, blockCount, status);
+
+ return status == (blockCount * blksize);
+#else
+ int result;
+ int retries = 10;
+
+ if (blockCount == 0)
+ return blockCount;
+ while(--retries) {
+ result = call_method_1 ("read-blocks", dev, 3, buffer, blockNum, blockCount);
+ if (result != 0)
+ break;
+ call_prom("interpret", 1, 1, " 10 ms");
+ }
+
+ return result;
+#endif
+}
+
+int
+prom_getchar ()
+{
+ char c[4];
+ int a;
+
+ 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];
+}
+
+int
+prom_nbgetchar()
+{
+ char ch;
+
+ return (int) call_prom("read", 3, 1, prom_stdin, &ch, 1) > 0? ch: -1;
+}
+
+void
+prom_putchar (char c)
+{
+ if (c == '\n')
+ call_prom ("write", 3, 1, prom_stdout, "\r\n", 2);
+ else
+ call_prom ("write", 3, 1, prom_stdout, &c, 1);
+}
+
+void
+prom_puts (prom_handle file, char *s)
+{
+ const char *p, *q;
+
+ for (p = s; *p != 0; p = q)
+ {
+ for (q = p; *q != 0 && *q != '\n'; ++q)
+ ;
+ if (q > p)
+ call_prom ("write", 3, 1, file, p, q - p);
+ if (*q != 0)
+ {
+ ++q;
+ call_prom ("write", 3, 1, file, "\r\n", 2);
+ }
+ }
+}
+
+void
+prom_vfprintf (prom_handle file, char *fmt, va_list ap)
+{
+ static char printf_buf[1024];
+ vsprintf (printf_buf, fmt, ap);
+ prom_puts (file, printf_buf);
+}
+
+void
+prom_vprintf (char *fmt, va_list ap)
+{
+ static char printf_buf[1024];
+ vsprintf (printf_buf, fmt, ap);
+ prom_puts (prom_stdout, printf_buf);
+}
+
+void
+prom_fprintf (prom_handle file, char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ prom_vfprintf (file, fmt, ap);
+ va_end (ap);
+}
+
+void
+prom_printf (char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ prom_vfprintf (prom_stdout, fmt, ap);
+ va_end (ap);
+}
+
+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)
+{
+ return (int)call_prom( "call-method", 6, 1, "color!", device, color, b, g, r );
+}
+#endif /* CONFIG_SET_COLORMAP */
+
+void
+prom_exit ()
+{
+ call_prom ("exit", 0, 0);
+}
+
+void
+prom_abort (char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ prom_vfprintf (prom_stdout, fmt, ap);
+ va_end (ap);
+ prom_exit ();
+}
+
+void *
+prom_claim (void *virt, unsigned int size, unsigned int align)
+{
+ return call_prom ("claim", 3, 1, virt, size, align);
+}
+
+void
+prom_release(void *virt, unsigned int size)
+{
+// call_prom ("release", 2, 1, virt, size);
+ /* release in not enough, it needs also an unmap call. This bit of forth
+ * code inspired from Darwin's bootloader but could be replaced by direct
+ * calls to the MMU package if needed
+ */
+ call_prom ("interpret", 3, 1,
+#if DEBUG
+ ".\" ReleaseMem:\" 2dup . . cr "
+#endif
+ "over \" translate\" ^mmu " // Find out physical base
+ "^on0 " // Bail if translation failed
+ "drop " // Leaving phys on top of stack
+ "2dup \" unmap\" ^mmu " // Unmap the space first
+ "2dup \" release\" ^mmu " // Then free the virtual pages
+ "\" release\" ^mem " // Then free the physical pages
+ ,size, virt
+ );
+}
+
+void
+prom_map (void *phys, void *virt, int size)
+{
+ unsigned long msr = mfmsr();
+
+ /* Only create a mapping if we're running with relocation enabled. */
+ if ( (msr & MSR_IR) && (msr & MSR_DR) )
+ call_method_1 ("map", prom_mmu, 4, -1, size, virt, phys);
+}
+
+void
+prom_unmap (void *phys, void *virt, int size)
+{
+ unsigned long msr = mfmsr();
+
+ /* Only unmap if we're running with relocation enabled. */
+ if ( (msr & MSR_IR) && (msr & MSR_DR) )
+ call_method_1 ("map", prom_mmu, 4, -1, size, virt, phys);
+}
+
+char *
+prom_getargs ()
+{
+ static char args[256];
+ int l;
+
+ l = prom_get_chosen ("bootargs", args, 255);
+ args[l] = '\0';
+ return args;
+}
+
+void
+prom_setargs (char *args)
+{
+ int l = strlen (args)+1;
+ if ((int)call_prom ("setprop", 4, 1, prom_chosen, "bootargs", args, l) != l)
+ prom_printf ("can't set args\n");
+}
+
+int prom_interpret (char *forth)
+{
+ return (int)call_prom("interpret", 1, 1, forth);
+}
+
+int
+prom_getms(void)
+{
+ return (int) call_prom("milliseconds", 0, 1);
+}
+
+void
+prom_pause(void)
+{
+ call_prom("enter", 0, 0);
+}
+
--- /dev/null
+ .globl __sigsetjmp
+__sigsetjmp:
+ mflr 0
+ stw 1,0(3)
+ stw 2,4(3)
+ stw 0,8(3)
+ stw 14,12(3)
+ stw 15,16(3)
+ stw 16,20(3)
+ stw 17,24(3)
+ stw 18,28(3)
+ stw 19,32(3)
+ stw 20,36(3)
+ stw 21,40(3)
+ stw 22,44(3)
+ stw 23,48(3)
+ stw 24,52(3)
+ stw 25,56(3)
+ stw 26,60(3)
+ stw 27,64(3)
+ stw 28,68(3)
+ stw 29,72(3)
+ stw 30,76(3)
+ stw 31,80(3)
+ li 3,0
+ blr
+
+ .globl longjmp
+longjmp:
+ cmpwi 0,4,0
+ bne 1f
+ li 4,1
+1: lwz 1,0(3)
+ lwz 2,4(3)
+ lwz 0,8(3)
+ lwz 14,12(3)
+ lwz 15,16(3)
+ lwz 16,20(3)
+ lwz 17,24(3)
+ lwz 18,28(3)
+ lwz 19,32(3)
+ lwz 20,36(3)
+ lwz 21,40(3)
+ lwz 22,44(3)
+ lwz 23,48(3)
+ lwz 24,52(3)
+ lwz 25,56(3)
+ lwz 26,60(3)
+ lwz 27,64(3)
+ lwz 28,68(3)
+ lwz 29,72(3)
+ lwz 30,76(3)
+ lwz 31,80(3)
+ mtlr 0
+ mr 3,4
+ blr
--- /dev/null
+/* Yaboot - secondary boot loader for Linux on ppc.
+
+ Copyright (C) 1999 Benjamin Herrenschmidt
+
+ portions based on poof
+
+ Copyright (C) 1999 Marius Vollmer
+
+ portions based on quik
+
+ Copyright (C) 1996 Paul Mackerras.
+
+ Because this program is derived from the corresponding file in the
+ silo-0.64 distribution, it is also
+sys
+ Copyright (C) 1996 Pete A. Zaitcev
+ 1996 Maurizio Plaza
+ 1996 David S. Miller
+ 1996 Miguel de Icaza
+ 1996 Jakub Jelinek
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "stdarg.h"
+#include "string.h"
+#include "ctype.h"
+#include "stdlib.h"
+#include "prom.h"
+#include "file.h"
+#include "cfg.h"
+#include "cmdline.h"
+#include "yaboot.h"
+#include "linux/elf.h"
+#include "bootinfo.h"
+
+#define CONFIG_FILE_NAME "yaboot.conf"
+#define CONFIG_FILE_MAX 0x8000 /* 32k */
+
+#ifdef CONFIG_SPLASH_SCREEN
+#include "gui.h"
+#endif /* CONFIG_SPLASH_SCREEN */
+
+#ifdef USE_MD5_PASSWORDS
+#include "md5.h"
+#endif /* USE_MD5_PASSWORDS */
+
+/* align addr on a size boundry - adjust address up if needed -- Cort */
+#define _ALIGN(addr,size) (((addr)+size-1)&(~(size-1)))
+
+/* Addresses where the PPC32 and PPC64 vmlinux kernels are linked at.
+ * These are used to determine whether we are booting a vmlinux, in
+ * which case, it will be loaded at KERNELADDR. Otherwise (eg zImage),
+ * we load the binary where it was linked at (ie, e_entry field in
+ * the ELF header).
+ */
+#define KERNEL_LINK_ADDR_PPC32 0xC0000000UL
+#define KERNEL_LINK_ADDR_PPC64 0xC000000000000000ULL
+
+typedef struct {
+ union {
+ Elf32_Ehdr elf32hdr;
+ Elf64_Ehdr elf64hdr;
+ } elf;
+ void* base;
+ unsigned long memsize;
+ unsigned long filesize;
+ unsigned long offset;
+ unsigned long load_loc;
+ unsigned long entry;
+} loadinfo_t;
+
+typedef void (*kernel_entry_t)( void *,
+ unsigned long,
+ prom_entry,
+ unsigned long,
+ unsigned long );
+
+/* Imported functions */
+extern unsigned long reloc_offset(void);
+extern long flush_icache_range(unsigned long start, unsigned long stop);
+
+/* Exported functions */
+int yaboot_start(unsigned long r3, unsigned long r4, unsigned long r5);
+
+/* Local functions */
+static int yaboot_main(void);
+static int is_elf32(loadinfo_t *loadinfo);
+static int is_elf64(loadinfo_t *loadinfo);
+static int load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo);
+static int load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo);
+static void setup_display(void);
+
+/* Locals & globals */
+
+int useconf = 0;
+char bootdevice[1024];
+char *bootpath = NULL;
+char *password = NULL;
+int bootpartition = -1;
+int _machine = _MACH_Pmac;
+
+#ifdef CONFIG_COLOR_TEXT
+
+/* Color values for text ui */
+static struct ansi_color_t {
+ char* name;
+ int index;
+ int value;
+} ansi_color_table[] = {
+ { "black", 2, 30 },
+ { "blue", 0, 31 },
+ { "green", 0, 32 },
+ { "cyan", 0, 33 },
+ { "red", 0, 34 },
+ { "purple", 0, 35 },
+ { "brown", 0, 36 },
+ { "light-gray", 0, 37 },
+ { "dark-gray", 1, 30 },
+ { "light-blue", 1, 31 },
+ { "light-green", 1, 32 },
+ { "light-cyan", 1, 33 },
+ { "light-red", 1, 34 },
+ { "light-purple", 1, 35 },
+ { "yellow", 1, 36 },
+ { "white", 1, 37 },
+ { NULL, 0, 0 },
+};
+
+/* Default colors for text ui */
+int fgcolor = 15;
+int bgcolor = 0;
+#endif /* CONFIG_COLOR_TEXT */
+
+#if DEBUG
+static int test_bss;
+static int test_data = 0;
+#endif
+static int pause_after;
+static char *pause_message = "Type go<return> to continue.\n";
+static char given_bootargs[1024];
+static int given_bootargs_by_user = 0;
+
+extern unsigned char linux_logo_red[];
+extern unsigned char linux_logo_green[];
+extern unsigned char linux_logo_blue[];
+
+#define DEFAULT_TIMEOUT -1
+
+/* Entry, currently called directly by crt0 (bss not inited) */
+
+extern char* __bss_start;
+extern char* _end;
+
+static struct first_info *quik_fip = NULL;
+
+int
+yaboot_start (unsigned long r3, unsigned long r4, unsigned long r5)
+{
+ int result;
+ void* malloc_base = NULL;
+ prom_handle root;
+
+ /* OF seems to do it, but I'm not very confident */
+ memset(&__bss_start, 0, &_end - &__bss_start);
+
+ /* Check for quik first stage bootloader (but I don't think we are
+ * compatible with it anyway, I'll look into backporting to older OF
+ * versions later
+ */
+ if (r5 == 0xdeadbeef) {
+ r5 = r3;
+ quik_fip = (struct first_info *)r4;
+ }
+
+ /* Initialize OF interface */
+ prom_init ((prom_entry) r5);
+
+ /* Allocate some memory for malloc'ator */
+ malloc_base = prom_claim((void *)MALLOCADDR, MALLOCSIZE, 0);
+ if (malloc_base == (void *)-1) {
+ prom_printf("Can't claim malloc buffer (%d bytes at 0x%08lx)\n",
+ MALLOCSIZE, MALLOCADDR);
+ return -1;
+ }
+ malloc_init(malloc_base, MALLOCSIZE);
+#if DEBUG
+ prom_printf("Malloc buffer allocated at 0x%x (%d bytes)\n",
+ malloc_base, MALLOCSIZE);
+#endif
+
+ /* A few useless printf's */
+#if DEBUG
+ prom_printf("reloc_offset : %ld (should be 0)\n", reloc_offset());
+ prom_printf("test_bss : %d (should be 0)\n", test_bss);
+ prom_printf("test_data : %d (should be 0)\n", test_data);
+ prom_printf("&test_data : 0x%08lx\n", &test_data);
+ prom_printf("&test_bss : 0x%08lx\n", &test_bss);
+ prom_printf("linked at : 0x%08lx\n", TEXTADDR);
+#endif
+ /* ask the OF info if we're a chrp or pmac */
+ /* we need to set _machine before calling finish_device_tree */
+ root = prom_finddevice("/");
+ if (root != 0) {
+ static char model[256];
+ if (prom_getprop(root, "device_type", model, 256 ) > 0 &&
+ !strncmp("chrp", model, 4))
+ _machine = _MACH_chrp;
+ else {
+ if (prom_getprop(root, "model", model, 256 ) > 0 &&
+ !strncmp(model, "IBM", 3))
+ _machine = _MACH_chrp;
+ }
+ }
+
+#if DEBUG
+ prom_printf("Running on _machine = %d\n", _machine);
+#endif
+
+ /* Call out main */
+ result = yaboot_main();
+
+ /* Get rid of malloc pool */
+ malloc_dispose();
+ prom_release(malloc_base, MALLOCSIZE);
+#if DEBUG
+ prom_printf("Malloc buffer released. Exiting with code %d\n",
+ result);
+
+#endif
+
+ /* Return to OF */
+ prom_exit();
+
+ return result;
+
+}
+
+#ifdef CONFIG_COLOR_TEXT
+/*
+ * Validify color for text ui
+ */
+static int
+check_color_text_ui(char *color)
+{
+ int i = 0;
+ while(ansi_color_table[i].name) {
+ if (!strcmp(color, ansi_color_table[i].name))
+ return i;
+ i++;
+ }
+ return -1;
+}
+#endif /* CONFIG_COLOR_TEXT */
+
+/* Currently, the config file must be at the root of the filesystem.
+ * todo: recognize the full path to myself and use it to load the
+ * config file. Handle the "\\" (blessed system folder)
+ */
+static int
+load_config_file(char *device, char* path, int partition)
+{
+ char *conf_file = NULL, *p;
+ struct boot_file_t file;
+ int sz, opened = 0, result = 0;
+ char conf_path[512];
+ struct boot_fspec_t fspec;
+
+ /* Allocate a buffer for the config file */
+ conf_file = malloc(CONFIG_FILE_MAX);
+ if (!conf_file) {
+ prom_printf("Can't alloc config file buffer\n");
+ goto bail;
+ }
+
+ /* Build the path to the file */
+ if (path)
+ strcpy(conf_path, path);
+ else if ( _machine == _MACH_chrp )
+ strcpy(conf_path, "/etc/");
+ else
+ conf_path[0] = 0;
+ strcat(conf_path, CONFIG_FILE_NAME);
+
+ /* Open it */
+ fspec.dev = device;
+ fspec.file = conf_path;
+ fspec.part = partition;
+ result = open_file(&fspec, &file);
+ if (result != FILE_ERR_OK) {
+ prom_printf("Can't open config file '%s', err: %d\n", conf_path, result);
+ goto bail;
+ }
+ opened = 1;
+
+ /* Read it */
+ sz = file.fs->read(&file, CONFIG_FILE_MAX, conf_file);
+ if (sz <= 0) {
+ prom_printf("Error, can't read config file\n");
+ goto bail;
+ }
+ prom_printf("Config file read, %d bytes\n", sz);
+
+ /* Close the file */
+ if (opened)
+ file.fs->close(&file);
+ opened = 0;
+
+ /* Call the parsing code in cfg.c */
+ if (cfg_parse(conf_path, conf_file, sz) < 0) {
+ prom_printf ("Syntax error or read error config\n");
+ goto bail;
+ }
+
+#if DEBUG
+ prom_printf("Config file successfully parsed\n", sz);
+#endif
+
+ /* Now, we do the initialisations stored in the config file */
+ p = cfg_get_strg(0, "init-code");
+ if (p)
+ prom_interpret(p);
+
+ password = cfg_get_strg(0, "password");
+
+#ifdef CONFIG_COLOR_TEXT
+ p = cfg_get_strg(0, "fgcolor");
+ if (p) {
+#if DEBUG
+ prom_printf("fgcolor=%s\n", p);
+#endif
+ fgcolor = check_color_text_ui(p);
+ if (fgcolor == -1) {
+ prom_printf("Invalid fgcolor: \"%s\".\n", p);
+ }
+ }
+ p = cfg_get_strg(0, "bgcolor");
+ if (p) {
+#if DEBUG
+ prom_printf("bgcolor=%s\n", p);
+#endif
+ bgcolor = check_color_text_ui(p);
+ if (bgcolor == -1)
+ prom_printf("Invalid bgcolor: \"%s\".\n", p);
+ }
+ if (bgcolor >= 0) {
+ char temp[64];
+ sprintf(temp, "%x to background-color", bgcolor);
+ prom_interpret(temp);
+#if !DEBUG
+ prom_printf("\xc");
+#endif
+ }
+ if (fgcolor >= 0) {
+ char temp[64];
+ sprintf(temp, "%x to foreground-color", fgcolor);
+ prom_interpret(temp);
+ }
+#endif /* CONFIG_COLOR_TEXT */
+
+ p = cfg_get_strg(0, "init-message");
+ if (p)
+ prom_printf("%s\n", p);
+#if 0
+ p = cfg_get_strg(0, "message");
+ if (p)
+ print_message_file(p);
+#endif
+
+ result = 1;
+
+bail:
+
+ if (opened)
+ file.fs->close(&file);
+
+ if (result != 1 && conf_file)
+ free(conf_file);
+
+ return result;
+}
+
+void maintabfunc (void)
+{
+ if (useconf) {
+ cfg_print_images();
+ prom_printf("boot: %s", cbuff);
+ }
+}
+
+void
+word_split(char **linep, char **paramsp)
+{
+ char *p;
+
+ *paramsp = 0;
+ p = *linep;
+ if (p == 0)
+ return;
+ while (*p == ' ')
+ ++p;
+ if (*p == 0) {
+ *linep = 0;
+ return;
+ }
+ *linep = p;
+ while (*p != 0 && *p != ' ')
+ ++p;
+ while (*p == ' ')
+ *p++ = 0;
+ if (*p != 0)
+ *paramsp = p;
+}
+
+char *
+make_params(char *label, char *params)
+{
+ char *p, *q;
+ static char buffer[2048];
+
+ q = buffer;
+ *q = 0;
+
+ p = cfg_get_strg(label, "literal");
+ if (p) {
+ strcpy(q, p);
+ q = strchr(q, 0);
+ if (params) {
+ if (*p)
+ *q++ = ' ';
+ strcpy(q, params);
+ }
+ return buffer;
+ }
+
+ p = cfg_get_strg(label, "root");
+ if (p) {
+ strcpy (q, "root=");
+ strcpy (q + 5, p);
+ q = strchr (q, 0);
+ *q++ = ' ';
+ }
+ if (cfg_get_flag(label, "read-only")) {
+ strcpy (q, "ro ");
+ q += 3;
+ }
+ if (cfg_get_flag(label, "read-write")) {
+ strcpy (q, "rw ");
+ q += 3;
+ }
+ p = cfg_get_strg(label, "ramdisk");
+ if (p) {
+ strcpy (q, "ramdisk=");
+ strcpy (q + 8, p);
+ q = strchr (q, 0);
+ *q++ = ' ';
+ }
+ p = cfg_get_strg(label, "initrd-size");
+ if (p) {
+ strcpy (q, "ramdisk_size=");
+ strcpy (q + 13, p);
+ q = strchr (q, 0);
+ *q++ = ' ';
+ }
+ if (cfg_get_flag(label, "novideo")) {
+ strcpy (q, "video=ofonly");
+ q = strchr (q, 0);
+ *q++ = ' ';
+ }
+ p = cfg_get_strg (label, "append");
+ if (p) {
+ strcpy (q, p);
+ q = strchr (q, 0);
+ *q++ = ' ';
+ }
+ *q = 0;
+ pause_after = cfg_get_flag (label, "pause-after");
+ p = cfg_get_strg(label, "pause-message");
+ if (p)
+ pause_message = p;
+ if (params)
+ strcpy(q, params);
+
+ return buffer;
+}
+
+void check_password(char *str)
+{
+ int i, end;
+
+ for (i = 0; i < 3; i++) {
+ prom_printf ("\n%sassword: ", str);
+ passwdbuff[0] = 0;
+ cmdedit ((void (*)(void)) 0, 1);
+ prom_printf ("\n");
+#ifdef USE_MD5_PASSWORDS
+ if (!strncmp (password, "$1$", 3)) {
+ if (!check_md5_password(passwdbuff, password))
+ return;
+ }
+ else if (!strcmp (password, passwdbuff))
+ return;
+#else
+ if (!strcmp (password, passwdbuff))
+ return;
+#endif
+ if (i < 2)
+ prom_printf ("Password incorrect. Please try again...");
+ }
+ prom_printf ("Seems like you don't know the access password. Go away!\n");
+ end = (prom_getms() + 3000);
+ while (prom_getms() <= end);
+ prom_interpret("reset-all");
+}
+
+int get_params(struct boot_param_t* params)
+{
+ int defpart;
+ char *defdevice = 0;
+ char *p, *q, *endp;
+ int c, n;
+ char *imagename = 0, *label;
+ int timeout = -1;
+ int beg = 0, end;
+ int singlekey = 0;
+ int restricted = 0;
+ static int first = 1;
+ static char bootargs[1024];
+ static char imagepath[1024];
+ static char initrdpath[1024];
+ static char sysmappath[1024];
+#ifdef CONFIG_SPLASH_SCREEN
+ static char splashpath[1024];
+#endif /* CONFIG_SPLASH_SCREEN */
+
+ pause_after = 0;
+ memset(params, 0, sizeof(*params));
+ params->args = "";
+ params->kernel.part = -1;
+ params->rd.part = -1;
+ params->sysmap.part = -1;
+ params->splash.part = -1;
+ defpart = bootpartition;
+
+ cmdinit();
+
+ if (first) {
+ first = 0;
+ prom_get_chosen("bootargs", bootargs, sizeof(bootargs));
+ imagename = bootargs;
+ word_split(&imagename, ¶ms->args);
+ timeout = DEFAULT_TIMEOUT;
+ if (imagename) {
+ prom_printf("Default supplied on the command line: ");
+ prom_printf("%s ", imagename);
+ if (params->args)
+ prom_printf("%s", params->args);
+ prom_printf("\n");
+ }
+ if (useconf && (q = cfg_get_strg(0, "timeout")) != 0 && *q != 0)
+ timeout = simple_strtol(q, NULL, 0);
+ }
+
+ prom_printf("boot: ");
+ c = -1;
+ if (timeout != -1) {
+ beg = prom_getms();
+ if (timeout > 0) {
+ end = beg + 100 * timeout;
+ do {
+ c = prom_nbgetchar();
+ } while (c == -1 && prom_getms() <= end);
+ }
+ if (c == -1)
+ c = '\n';
+ else if (c != '\n' && c != '\t' && c != '\r' && c != '\b' ) {
+ cbuff[0] = c;
+ cbuff[1] = 0;
+ }
+ }
+
+ if (c != -1 && c != '\n' && c != '\r') {
+ if (c == '\t') {
+ maintabfunc ();
+ } else if (c >= ' ') {
+ cbuff[0] = c;
+ cbuff[1] = 0;
+ if ((cfg_get_flag (cbuff, "single-key")) && useconf) {
+ imagename = cbuff;
+ singlekey = 1;
+ prom_printf("%s\n", cbuff);
+ }
+ }
+ }
+
+ if (c == '\n' || c == '\r') {
+ if (!imagename)
+ imagename = cfg_get_default();
+ if (imagename)
+ prom_printf("%s", imagename);
+ if (params->args)
+ prom_printf(" %s", params->args);
+ prom_printf("\n");
+ } else if (!singlekey) {
+ cmdedit(maintabfunc, 0);
+ prom_printf("\n");
+ strcpy(given_bootargs, cbuff);
+ given_bootargs_by_user = 1;
+ imagename = cbuff;
+ word_split(&imagename, ¶ms->args);
+ }
+
+ /* chrp gets this wrong, force it -- Cort */
+ if ( useconf && (!imagename || imagename[0] == 0 ))
+ imagename = cfg_get_default();
+
+ label = 0;
+ defdevice = bootdevice;
+
+ if (useconf) {
+ defdevice = cfg_get_strg(0, "device");
+ p = cfg_get_strg(0, "partition");
+ if (p) {
+ n = simple_strtol(p, &endp, 10);
+ if (endp != p && *endp == 0)
+ defpart = n;
+ }
+ p = cfg_get_strg(0, "pause-message");
+ if (p)
+ pause_message = p;
+ if (cfg_get_flag(0, "restricted"))
+ restricted = 1;
+ p = cfg_get_strg(imagename, "image");
+ if (p && *p) {
+ label = imagename;
+ imagename = p;
+ defdevice = cfg_get_strg(label, "device");
+ if(!defdevice) defdevice=bootdevice;
+ p = cfg_get_strg(label, "partition");
+ if (p) {
+ n = simple_strtol(p, &endp, 10);
+ if (endp != p && *endp == 0)
+ defpart = n;
+ }
+ if (cfg_get_flag(label, "restricted"))
+ restricted = 1;
+ if (label) {
+ if (params->args && password && restricted)
+ check_password ("To specify image arguments you must enter the p");
+ else if (password && !restricted)
+ check_password ("P");
+ }
+ params->args = make_params(label, params->args);
+ }
+ }
+
+ if (!strcmp (imagename, "halt")) {
+ if (password)
+ check_password ("P");
+ prom_pause();
+ return 0;
+ }
+ if (!strcmp (imagename, "bye")) {
+ if (password) {
+ check_password ("P");
+ return 1;
+ }
+ return 1;
+ }
+
+ if (imagename[0] == '$') {
+ /* forth command string */
+ if (password)
+ check_password ("P");
+ prom_interpret(imagename+1);
+ return 0;
+ }
+
+ strncpy(imagepath, imagename, 1024);
+
+ if (!label && password)
+ check_password ("To boot a custom image you must enter the p");
+
+ params->kernel.dev = parse_device_path(imagepath, ¶ms->kernel.file,
+ ¶ms->kernel.part);
+ if (validate_fspec(¶ms->kernel, defdevice, defpart) != FILE_ERR_OK) {
+ prom_printf(
+"Enter the kernel image name as [device:][partno]/path, where partno is a\n"
+"number from 0 to 16. Instead of /path you can type [mm-nn] to specify a\n"
+"range of disk blocks (512B)\n"
+"Example: hd:3,/vmlinux\n");
+ return 0;
+ }
+
+ if (useconf) {
+ p = cfg_get_strg(label, "initrd");
+ if (p && *p) {
+#if DEBUG
+ prom_printf("parsing initrd path <%s>\n", p);
+#endif
+ strncpy(initrdpath, p, 1024);
+ params->rd.dev = parse_device_path(initrdpath,
+ ¶ms->rd.file, ¶ms->rd.part);
+ validate_fspec(¶ms->rd, defdevice, defpart);
+ }
+ p = cfg_get_strg(label, "sysmap");
+ if (p && *p) {
+#if DEBUG
+ prom_printf("parsing sysmap path <%s>\n", p);
+#endif
+ strncpy(sysmappath, p, 1024);
+ params->sysmap.dev = parse_device_path(sysmappath,
+ ¶ms->sysmap.file, ¶ms->sysmap.part);
+ validate_fspec(¶ms->sysmap, defdevice, defpart);
+ }
+#ifdef CONFIG_SPLASH_SCREEN
+ p = cfg_get_strg(label, "splash");
+ if (p && *p) {
+#if DEBUG
+ prom_printf("parsing splash path <%s>\n", p);
+#endif
+ strncpy(splashpath, p, 1024);
+ params->splash.dev = parse_device_path(splashpath,
+ ¶ms->splash.file, ¶ms->splash.part);
+ validate_fspec(¶ms->splash, defdevice, defpart);
+ }
+#endif /* CONFIG_SPLASH_SCREEN */
+ }
+
+ return 0;
+}
+
+/* This is derived from quik core. To be changed to first parse the headers
+ * doing lazy-loading, and then claim the memory before loading the kernel
+ * to it
+ * We also need to add initrd support to this whole mecanism
+ */
+void
+yaboot_text_ui(void)
+{
+#define MAX_HEADERS 32
+
+ struct boot_file_t file;
+ int result;
+ static struct boot_param_t params;
+ void *initrd_base;
+ unsigned long initrd_size;
+ void *sysmap_base;
+ unsigned long sysmap_size;
+ kernel_entry_t kernel_entry;
+ struct bi_record* birec;
+ char* loc=NULL;
+ loadinfo_t loadinfo;
+ void *initrd_more,*initrd_want;
+ unsigned long initrd_read;
+
+ loadinfo.load_loc = 0;
+
+ for (;;) {
+ initrd_size = 0;
+ initrd_base = 0;
+ sysmap_base = 0;
+ sysmap_size = 0;
+
+ if (get_params(¶ms))
+ return;
+ if (!params.kernel.file)
+ continue;
+
+#ifdef CONFIG_SPLASH_SCREEN
+ if (params.splash.file)
+ fxDisplaySplash(¶ms.splash);
+#endif /* CONFIG_SPLASH_SCREEN */
+ prom_printf("Please wait, loading kernel...\n");
+
+ if(bootpath && !strcmp(bootpath,"\\\\") && params.kernel.file[0] != '/') {
+ loc=(char*)malloc(strlen(params.kernel.file)+3);
+ if (!loc) {
+ prom_printf ("malloc error\n");
+ goto next;
+ }
+ strcpy(loc,bootpath);
+ strcat(loc,params.kernel.file);
+ free(params.kernel.file);
+ params.kernel.file=loc;
+ }
+ result = open_file(¶ms.kernel, &file);
+ if (result != FILE_ERR_OK) {
+ prom_printf("\nImage not found.... try again\n");
+ goto next;
+ }
+
+ /* Read the Elf e_ident, e_type and e_machine fields to
+ * determine Elf file type
+ */
+ if (file.fs->read(&file, sizeof(Elf_Ident), &loadinfo.elf) < sizeof(Elf_Ident)) {
+ prom_printf("\nCan't read Elf e_ident/e_type/e_machine info\n");
+ goto next;
+ }
+
+ if ( is_elf32(&loadinfo) ) {
+ if ( !load_elf32(&file, &loadinfo) )
+ goto next;
+ prom_printf(" Elf32 kernel loaded...\n");
+ } else if ( is_elf64(&loadinfo) ) {
+ if ( !load_elf64(&file, &loadinfo) )
+ goto next;
+ prom_printf(" Elf64 kernel loaded...\n");
+ } else {
+ prom_printf ("Not a valid ELF image\n");
+ goto next;
+ }
+ file.fs->close(&file);
+
+ /* If sysmap, load it.
+ */
+ if (params.sysmap.file) {
+ prom_printf("Loading System.map ...\n");
+ if(bootpath && !strcmp(bootpath,"\\\\") && params.sysmap.file[0] != '/') {
+ if (loc) free(loc);
+ loc=(char*)malloc(strlen(params.sysmap.file)+3);
+ if (!loc) {
+ prom_printf ("malloc error\n");
+ goto next;
+ }
+ strcpy(loc,bootpath);
+ strcat(loc,params.sysmap.file);
+ free(params.sysmap.file);
+ params.sysmap.file=loc;
+ }
+
+ result = open_file(¶ms.sysmap, &file);
+ if (result != FILE_ERR_OK)
+ prom_printf("\nSystem.map file not found.\n");
+ else {
+ sysmap_base = prom_claim(loadinfo.base+loadinfo.memsize, 0x100000, 0);
+ if (sysmap_base == (void *)-1) {
+ prom_printf("claim failed for sysmap memory\n");
+ sysmap_base = 0;
+ } else {
+ sysmap_size = file.fs->read(&file, 0xfffff, sysmap_base);
+ if (sysmap_size == 0)
+ sysmap_base = 0;
+ else
+ ((char *)sysmap_base)[sysmap_size++] = 0;
+ }
+ file.fs->close(&file);
+ }
+ if (sysmap_base) {
+ prom_printf("System.map loaded at 0x%08lx, size: %d Kbytes\n",
+ sysmap_base, sysmap_size >> 10);
+ loadinfo.memsize += _ALIGN(0x100000, 0x1000);
+ } else {
+ prom_printf("System.map load failed !\n");
+ prom_pause();
+ }
+ }
+
+ /* If ramdisk, load it. For now, we can't tell the size it will be
+ * so we claim an arbitrary amount of 4Mb
+ */
+ if (params.rd.file) {
+ if(bootpath && !strcmp(bootpath,"\\\\") && params.rd.file[0] != '/')
+ {
+ if (loc) free(loc);
+ loc=(char*)malloc(strlen(params.rd.file)+3);
+ if (!loc) {
+ prom_printf ("malloc error\n");
+ goto next;
+ }
+ strcpy(loc,bootpath);
+ strcat(loc,params.rd.file);
+ free(params.rd.file);
+ params.rd.file=loc;
+ }
+ prom_printf("Loading ramdisk...\n");
+ result = open_file(¶ms.rd, &file);
+ if (result != FILE_ERR_OK)
+ prom_printf("\nRamdisk image not found.\n");
+ else {
+#define INITRD_CHUNKSIZE 0x400000
+ initrd_base = prom_claim(loadinfo.base+loadinfo.memsize, INITRD_CHUNKSIZE, 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);
+ 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);
+ if (initrd_more != initrd_want) {
+ prom_printf("claim failed for initrd memory at %x rc=%x\n",initrd_want,initrd_more);
+ break;
+ }
+ initrd_read = file.fs->read(&file, INITRD_CHUNKSIZE, initrd_more);
+#if DEBUG
+ prom_printf(" block at %x rc=%x\n",initrd_more,initrd_read);
+#endif
+ initrd_size += initrd_read;
+ }
+ }
+ file.fs->close(&file);
+ }
+ if (initrd_base)
+ prom_printf("ramdisk loaded at 0x%08lx, size: %d Kbytes\n",
+ initrd_base, initrd_size >> 10);
+ else {
+ prom_printf("ramdisk load failed !\n");
+ prom_pause();
+ }
+ }
+
+#if DEBUG
+ prom_printf("setting kernel args to: %s\n", params.args);
+#endif
+ prom_setargs(params.args);
+#if DEBUG
+ prom_printf("flushing icache...");
+#endif
+ flush_icache_range ((long)loadinfo.base, (long)loadinfo.base+loadinfo.memsize);
+#if DEBUG
+ prom_printf(" done\n");
+#endif
+
+ /*
+ * Fill mew boot infos
+ *
+ * The birec is low on memory, probably inside the malloc pool, so
+ * we don't write it earlier. At this point, we should not use anything
+ * coming from the malloc pool
+ */
+ birec = (struct bi_record *)_ALIGN(loadinfo.filesize+(1<<20)-1,(1<<20));
+
+ /* We make sure it's mapped. We map only 64k for now, it's plenty enough
+ * we don't claim since this precise memory range may already be claimed
+ * by the malloc pool
+ */
+ prom_map (birec, birec, 0x10000);
+#if DEBUG
+ prom_printf("birec at 0x%08lx\n", birec);
+ {
+ int i = prom_getms();
+ while((prom_getms() - i) < 2000)
+ ;
+ }
+#endif
+
+ birec->tag = BI_FIRST;
+ birec->size = sizeof(struct bi_record);
+ birec = (struct bi_record *)((unsigned long)birec + birec->size);
+
+ birec->tag = BI_BOOTLOADER_ID;
+ sprintf( (char *)birec->data, "yaboot");
+ birec->size = sizeof(struct bi_record) + strlen("yaboot") + 1;
+ birec = (struct bi_record *)((unsigned long)birec + birec->size);
+
+ birec->tag = BI_MACHTYPE;
+ birec->data[0] = _machine;
+ birec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ birec = (struct bi_record *)((unsigned long)birec + birec->size);
+
+ if (sysmap_base) {
+ birec->tag = BI_SYSMAP;
+ birec->data[0] = (unsigned long)sysmap_base;
+ birec->data[1] = sysmap_size;
+ birec->size = sizeof(struct bi_record) + sizeof(unsigned long)*2;
+ birec = (struct bi_record *)((unsigned long)birec + birec->size);
+ }
+ birec->tag = BI_LAST;
+ birec->size = sizeof(struct bi_record);
+ birec = (struct bi_record *)((unsigned long)birec + birec->size);
+
+ /* compute the kernel's entry point. */
+ kernel_entry = loadinfo.base + loadinfo.entry - loadinfo.load_loc;
+
+#if DEBUG
+ prom_printf("Kernel entry point = 0x%08lx\n", kernel_entry);
+ prom_printf("kernel: arg1 = 0x%08lx,\n"
+ " arg2 = 0x%08lx,\n"
+ " prom = 0x%08lx,\n"
+ " arg4 = 0x%08lx,\n"
+ " arg5 = 0x%08lx\n\n",
+ initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0);
+
+#endif
+
+#if DEBUG
+ prom_printf("entering kernel...\n");
+#endif
+ /* call the kernel with our stack. */
+ kernel_entry(initrd_base + loadinfo.load_loc, initrd_size, prom, 0, 0);
+ continue;
+next:
+ if( file.fs != NULL )
+ file.fs->close(&file);
+ }
+}
+
+static int
+load_elf32(struct boot_file_t *file, loadinfo_t *loadinfo)
+{
+ int i;
+ Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr);
+ Elf32_Phdr *p, *ph;
+ int size = sizeof(Elf32_Ehdr) - sizeof(Elf_Ident);
+ unsigned long addr, loadaddr;
+
+ /* Read the rest of the Elf header... */
+ if ((*(file->fs->read))(file, size, &e->e_version) < size) {
+ prom_printf("\nCan't read Elf32 image header\n");
+ return 0;
+ }
+
+#if DEBUG
+ prom_printf("Elf32 header:\n");
+ prom_printf(" e.e_type = %d\n", (int)e->e_type);
+ prom_printf(" e.e_machine = %d\n", (int)e->e_machine);
+ prom_printf(" e.e_version = %d\n", (int)e->e_version);
+ prom_printf(" e.e_entry = 0x%08x\n", (int)e->e_entry);
+ prom_printf(" e.e_phoff = 0x%08x\n", (int)e->e_phoff);
+ prom_printf(" e.e_shoff = 0x%08x\n", (int)e->e_shoff);
+ prom_printf(" e.e_flags = %d\n", (int)e->e_flags);
+ prom_printf(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize);
+ prom_printf(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
+ prom_printf(" e.e_phnum = %d\n", (int)e->e_phnum);
+#endif
+
+ loadinfo->entry = e->e_entry;
+
+ if (e->e_phnum > MAX_HEADERS) {
+ prom_printf ("can only load kernels with one program header\n");
+ return 0;
+ }
+
+ ph = (Elf32_Phdr *)malloc(sizeof(Elf32_Phdr) * e->e_phnum);
+ if (!ph) {
+ prom_printf ("malloc error\n");
+ return 0;
+ }
+
+ /* Now, we read the section header */
+ if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
+ prom_printf ("seek error\n");
+ return 0;
+ }
+ if ((*(file->fs->read))(file, sizeof(Elf32_Phdr) * e->e_phnum, ph) !=
+ sizeof(Elf32_Phdr) * e->e_phnum) {
+ prom_printf ("read error\n");
+ return 0;
+ }
+
+ /* Scan through the program header
+ * HACK: We must return the _memory size of the kernel image, not the
+ * file size (because we have to leave room before other boot
+ * infos. This code works as a side effect of the fact that
+ * we have one section and vaddr == p_paddr
+ */
+ loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0;
+ p = ph;
+ for (i = 0; i < e->e_phnum; ++i, ++p) {
+ if (p->p_type != PT_LOAD || p->p_offset == 0)
+ continue;
+ if (loadinfo->memsize == 0) {
+ loadinfo->offset = p->p_offset;
+ loadinfo->memsize = p->p_memsz;
+ loadinfo->filesize = p->p_filesz;
+ loadinfo->load_loc = p->p_vaddr;
+ } else {
+ loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */
+ loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset;
+ }
+ }
+
+ if (loadinfo->memsize == 0) {
+ prom_printf("Can't find a loadable segment !\n");
+ return 0;
+ }
+
+ /* leave some room (1Mb) for boot infos */
+ loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
+ /* Claim OF memory */
+#if DEBUG
+ prom_printf("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
+#endif
+
+ /* On some systems, loadaddr may already be claimed, so try some
+ * other nearby addresses before giving up.
+ */
+ loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC32) ? KERNELADDR : e->e_entry;
+ for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
+ loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
+ if (loadinfo->base != (void *)-1) break;
+ }
+ if (loadinfo->base == (void *)-1) {
+ prom_printf("claim error, can't allocate kernel memory\n");
+ return 0;
+ }
+
+#if DEBUG
+ prom_printf("After ELF parsing, load base: 0x%08lx, mem_sz: 0x%08lx\n",
+ loadinfo->base, loadinfo->memsize);
+ prom_printf(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
+ loadaddr, loadinfo->memsize);
+#endif
+
+ /* Load the program segments... */
+ p = ph;
+ for (i = 0; i < e->e_phnum; ++i, ++p) {
+ unsigned long offset;
+ if (p->p_type != PT_LOAD || p->p_offset == 0)
+ continue;
+
+ /* Now, we skip to the image itself */
+ if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
+ prom_printf ("seek error\n");
+ prom_release(loadinfo->base, loadinfo->memsize);
+ return 0;
+ }
+ offset = p->p_vaddr - loadinfo->load_loc;
+#ifdef CONFIG_SPLASH_SCREEN
+ if (fxReadImage(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
+#else /* CONFIG_SPLASH_SCREEN */
+ if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
+#endif /* CONFIG_SPLASH_SCREEN */
+ prom_printf ("read failed\n");
+ prom_release(loadinfo->base, loadinfo->memsize);
+ return 0;
+ }
+ }
+
+#if 0 /* to make editor happy */
+ }
+#endif
+ (*(file->fs->close))(file);
+
+ free(ph);
+
+ /* Return success at loading the Elf32 kernel */
+ return 1;
+}
+
+static int
+load_elf64(struct boot_file_t *file, loadinfo_t *loadinfo)
+{
+ int i;
+ Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr);
+ Elf64_Phdr *p, *ph;
+ int size = sizeof(Elf64_Ehdr) - sizeof(Elf_Ident);
+ unsigned long addr, loadaddr;
+
+ /* Read the rest of the Elf header... */
+ if ((*(file->fs->read))(file, size, &e->e_version) < size) {
+ prom_printf("\nCan't read Elf64 image header\n");
+ return 0;
+ }
+
+#if DEBUG
+ prom_printf("Elf64 header:\n");
+ prom_printf(" e.e_type = %d\n", (int)e->e_type);
+ prom_printf(" e.e_machine = %d\n", (int)e->e_machine);
+ prom_printf(" e.e_version = %d\n", (int)e->e_version);
+ prom_printf(" e.e_entry = 0x%016lx\n", (long)e->e_entry);
+ prom_printf(" e.e_phoff = 0x%016lx\n", (long)e->e_phoff);
+ prom_printf(" e.e_shoff = 0x%016lx\n", (long)e->e_shoff);
+ prom_printf(" e.e_flags = %d\n", (int)e->e_flags);
+ prom_printf(" e.e_ehsize = 0x%08x\n", (int)e->e_ehsize);
+ prom_printf(" e.e_phentsize = 0x%08x\n", (int)e->e_phentsize);
+ prom_printf(" e.e_phnum = %d\n", (int)e->e_phnum);
+#endif
+
+ loadinfo->entry = e->e_entry;
+
+ if (e->e_phnum > MAX_HEADERS) {
+ prom_printf ("can only load kernels with one program header\n");
+ return 0;
+ }
+
+ ph = (Elf64_Phdr *)malloc(sizeof(Elf64_Phdr) * e->e_phnum);
+ if (!ph) {
+ prom_printf ("malloc error\n");
+ return 0;
+ }
+
+ /* Now, we read the section header */
+ if ((*(file->fs->seek))(file, e->e_phoff) != FILE_ERR_OK) {
+ prom_printf ("seek error\n");
+ return 0;
+ }
+ if ((*(file->fs->read))(file, sizeof(Elf64_Phdr) * e->e_phnum, ph) !=
+ sizeof(Elf64_Phdr) * e->e_phnum) {
+ prom_printf ("read error\n");
+ return 0;
+ }
+
+ /* Scan through the program header
+ * HACK: We must return the _memory size of the kernel image, not the
+ * file size (because we have to leave room before other boot
+ * infos. This code works as a side effect of the fact that
+ * we have one section and vaddr == p_paddr
+ */
+ loadinfo->memsize = loadinfo->filesize = loadinfo->offset = 0;
+ p = ph;
+ for (i = 0; i < e->e_phnum; ++i, ++p) {
+ if (p->p_type != PT_LOAD || p->p_offset == 0)
+ continue;
+ if (loadinfo->memsize == 0) {
+ loadinfo->offset = p->p_offset;
+ loadinfo->memsize = p->p_memsz;
+ loadinfo->filesize = p->p_filesz;
+ loadinfo->load_loc = p->p_vaddr;
+ } else {
+ loadinfo->memsize = p->p_offset + p->p_memsz - loadinfo->offset; /* XXX Bogus */
+ loadinfo->filesize = p->p_offset + p->p_filesz - loadinfo->offset;
+ }
+ }
+
+ if (loadinfo->memsize == 0) {
+ prom_printf("Can't find a loadable segment !\n");
+ return 0;
+ }
+
+ /* leave some room (1Mb) for boot infos */
+ loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
+ /* Claim OF memory */
+#if DEBUG
+ prom_printf("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
+#endif
+
+ /* On some systems, loadaddr may already be claimed, so try some
+ * other nearby addresses before giving up.
+ */
+ loadaddr = (e->e_entry == KERNEL_LINK_ADDR_PPC64) ? KERNELADDR : e->e_entry;
+ for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
+ loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
+ if (loadinfo->base != (void *)-1) break;
+ }
+ if (loadinfo->base == (void *)-1) {
+ prom_printf("claim error, can't allocate kernel memory\n");
+ return 0;
+ }
+
+#if DEBUG
+ prom_printf("After ELF parsing, load base: 0x%08lx, mem_sz: 0x%08lx\n",
+ loadinfo->base, loadinfo->memsize);
+ prom_printf(" wanted load base: 0x%08lx, mem_sz: 0x%08lx\n",
+ loadaddr, loadinfo->memsize);
+#endif
+
+ /* Load the program segments... */
+ p = ph;
+ for (i = 0; i < e->e_phnum; ++i, ++p) {
+ unsigned long offset;
+ if (p->p_type != PT_LOAD || p->p_offset == 0)
+ continue;
+
+ /* Now, we skip to the image itself */
+ if ((*(file->fs->seek))(file, p->p_offset) != FILE_ERR_OK) {
+ prom_printf ("seek error\n");
+ prom_release(loadinfo->base, loadinfo->memsize);
+ return 0;
+ }
+ offset = p->p_vaddr - loadinfo->load_loc;
+#ifdef CONFIG_SPLASH_SCREEN
+ if (fxReadImage(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
+#else /* CONFIG_SPLASH_SCREEN */
+ if ((*(file->fs->read))(file, p->p_filesz, loadinfo->base+offset) != p->p_filesz) {
+#endif /* CONFIG_SPLASH_SCREEN */
+ prom_printf ("read failed\n");
+ prom_release(loadinfo->base, loadinfo->memsize);
+ return 0;
+ }
+ }
+
+#if 0 /* to make editor happy */
+ }
+#endif
+ (*(file->fs->close))(file);
+
+ free(ph);
+
+ /* Return success at loading the Elf64 kernel */
+ return 1;
+}
+
+static int
+is_elf32(loadinfo_t *loadinfo)
+{
+ Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr);
+
+ return (e->e_ident[EI_MAG0] == ELFMAG0 &&
+ e->e_ident[EI_MAG1] == ELFMAG1 &&
+ e->e_ident[EI_MAG2] == ELFMAG2 &&
+ e->e_ident[EI_MAG3] == ELFMAG3 &&
+ e->e_ident[EI_CLASS] == ELFCLASS32 &&
+ e->e_ident[EI_DATA] == ELFDATA2MSB &&
+ e->e_type == ET_EXEC &&
+ e->e_machine == EM_PPC);
+}
+
+static int
+is_elf64(loadinfo_t *loadinfo)
+{
+ Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr);
+
+ return (e->e_ident[EI_MAG0] == ELFMAG0 &&
+ e->e_ident[EI_MAG1] == ELFMAG1 &&
+ e->e_ident[EI_MAG2] == ELFMAG2 &&
+ 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_machine == EM_PPC64);
+}
+
+static void
+setup_display(void)
+{
+#ifdef CONFIG_SET_COLORMAP
+ static unsigned char default_colors[] = {
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00,
+ 0x00, 0xaa, 0xaa,
+ 0xaa, 0x00, 0x00,
+ 0xaa, 0x00, 0xaa,
+ 0xaa, 0x55, 0x00,
+ 0xaa, 0xaa, 0xaa,
+ 0x55, 0x55, 0x55,
+ 0x55, 0x55, 0xff,
+ 0x55, 0xff, 0x55,
+ 0x55, 0xff, 0xff,
+ 0xff, 0x55, 0x55,
+ 0xff, 0x55, 0xff,
+ 0xff, 0xff, 0x55,
+ 0xff, 0xff, 0xff
+ };
+ int i, result;
+ prom_handle scrn = PROM_INVALID_HANDLE;
+
+ /* Try Apple's mac-boot screen ihandle */
+ result = (int)call_prom_return("interpret", 1, 2,
+ "\" _screen-ihandle\" $find if execute else 0 then", &scrn);
+#if DEBUG
+ prom_printf("trying to get screen ihandle, result: 0x%x, scrn: 0x%x\n", result, scrn);
+#endif
+ if (scrn == 0 || scrn == PROM_INVALID_HANDLE) {
+ char type[32];
+ /* Hrm... check to see if stdout is a display */
+ scrn = call_prom ("instance-to-package", 1, 1, prom_stdout);
+#if DEBUG
+ prom_printf("instance-to-package of stdout is: 0x%x\n", scrn);
+#endif
+ if (prom_getprop(scrn, "device_type", type, 32) > 0 && !strncmp(type, "display", 7)) {
+#if DEBUG
+ prom_printf("got it ! stdout is a screen\n");
+#endif
+ scrn = prom_stdout;
+ } else {
+ /* Else, we try to open the package */
+ scrn = (prom_handle)call_prom( "open", 1, 1, "screen" );
+#if DEBUG
+ prom_printf("Open screen result: 0x%x\n", scrn);
+#endif
+ }
+ }
+
+ if (scrn == PROM_INVALID_HANDLE) {
+ prom_printf("no screen device found !/n");
+ return;
+ }
+ for(i=0;i<16;i++) {
+ prom_set_color(scrn, i, default_colors[i*3],
+ default_colors[i*3+1], default_colors[i*3+2]);
+ }
+ prom_printf("\x1b[1;37m\x1b[2;40m");
+#ifdef COLOR_TEST
+ for (i=0;i<16; i++) {
+ prom_printf("\x1b[%d;%dm\x1b[1;47m%s \x1b[2;40m %s\n",
+ ansi_color_table[i].index,
+ ansi_color_table[i].value,
+ ansi_color_table[i].name,
+ ansi_color_table[i].name);
+ prom_printf("\x1b[%d;%dm\x1b[1;37m%s \x1b[2;30m %s\n",
+ ansi_color_table[i].index,
+ ansi_color_table[i].value+10,
+ ansi_color_table[i].name,
+ ansi_color_table[i].name);
+ }
+ prom_printf("\x1b[1;37m\x1b[2;40m");
+#endif
+#if !DEBUG
+ prom_printf("\xc");
+#endif
+#endif /* CONFIG_SET_COLORMAP */
+}
+
+int
+yaboot_main(void)
+{
+ if (_machine == _MACH_Pmac)
+ setup_display();
+
+ prom_get_chosen("bootpath", bootdevice, sizeof(bootdevice));
+#if DEBUG
+ prom_printf("/chosen/bootpath = %s\n", bootdevice);
+#endif
+ if (bootdevice[0] == 0)
+ prom_get_options("boot-device", bootdevice, sizeof(bootdevice));
+ if (bootdevice[0] == 0) {
+ prom_printf("Couldn't determine boot device\n");
+ return -1;
+ }
+ parse_device_path(bootdevice, &bootpath, &bootpartition);
+#if DEBUG
+ prom_printf("after parse_device_path: device:%s, path: %s, partition: %d\n",
+ bootdevice, bootpath ? bootpath : NULL, bootpartition);
+#endif
+ if (bootpath) {
+ if (!strncmp(bootpath, "\\\\", 2))
+ bootpath[2] = 0;
+ else {
+ char *p, *last;
+ p = last = bootpath;
+ while(*p) {
+ if (*p == '\\')
+ last = p;
+ p++;
+ }
+ if (p)
+ *(last) = 0;
+ else
+ bootpath = NULL;
+ if (bootpath && strlen(bootpath))
+ strcat(bootpath, "\\");
+ }
+ }
+#if DEBUG
+ prom_printf("after path fixup: device:%s, path: %s, partition: %d\n",
+ bootdevice, bootpath ? bootpath : NULL, bootpartition);
+#endif
+ useconf = load_config_file(bootdevice, bootpath, bootpartition);
+
+ prom_printf("Welcome to yaboot version " VERSION "\n");
+
+ yaboot_text_ui();
+
+ prom_printf("Bye.\n");
+ return 0;
+}
--- /dev/null
+/*
+ * Program to hack in a PT_NOTE program header entry in an ELF file.
+ * This is needed for OF on RS/6000s to load an image correctly.
+ * Note that OF needs a program header entry for the note, not an
+ * ELF section.
+ *
+ * Copyright 2000 Paul Mackerras.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Usage: addnote zImage
+ */
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+char arch[] = "PowerPC";
+
+#define N_DESCR 6
+unsigned int descr[N_DESCR] = {
+ 0xffffffff, /* real-mode = true */
+ 0x00c00000, /* real-base, i.e. where we expect OF to be */
+ 0xffffffff, /* real-size */
+ 0xffffffff, /* virt-base */
+ 0xffffffff, /* virt-size */
+ 0x4000, /* load-base */
+};
+
+unsigned char buf[512];
+
+#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1]))
+#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2))
+#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \
+ buf[(off) + 1] = (v) & 0xff)
+#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \
+ PUT_16BE((off) + 2, (v)))
+
+/* Structure of an ELF file */
+#define E_IDENT 0 /* ELF header */
+#define E_PHOFF 28
+#define E_PHENTSIZE 42
+#define E_PHNUM 44
+#define E_HSIZE 52 /* size of ELF header */
+
+#define EI_MAGIC 0 /* offsets in E_IDENT area */
+#define EI_CLASS 4
+#define EI_DATA 5
+
+#define PH_TYPE 0 /* ELF program header */
+#define PH_OFFSET 4
+#define PH_FILESZ 16
+#define PH_HSIZE 32 /* size of program header */
+
+#define PT_NOTE 4 /* Program header type = note */
+
+#define ELFCLASS32 1
+#define ELFDATA2MSB 2
+
+unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' };
+
+int
+main(int ac, char **av)
+{
+ int fd, n, i;
+ int ph, ps, np;
+ int nnote, ns;
+
+ if (ac != 2) {
+ fprintf(stderr, "Usage: %s elf-file\n", av[0]);
+ exit(1);
+ }
+ fd = open(av[1], O_RDWR);
+ if (fd < 0) {
+ perror(av[1]);
+ exit(1);
+ }
+
+ nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4;
+
+ n = read(fd, buf, sizeof(buf));
+ if (n < 0) {
+ perror("read");
+ exit(1);
+ }
+
+ if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
+ goto notelf;
+
+ if (buf[E_IDENT+EI_CLASS] != ELFCLASS32
+ || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
+ fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
+ av[1]);
+ exit(1);
+ }
+
+ ph = GET_32BE(E_PHOFF);
+ ps = GET_16BE(E_PHENTSIZE);
+ np = GET_16BE(E_PHNUM);
+ if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
+ goto notelf;
+ if (ph + (np + 1) * ps + nnote > n)
+ goto nospace;
+
+ for (i = 0; i < np; ++i) {
+ if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
+ fprintf(stderr, "%s already has a note entry\n",
+ av[1]);
+ exit(0);
+ }
+ ph += ps;
+ }
+
+ /* XXX check that the area we want to use is all zeroes */
+ for (i = 0; i < ps + nnote; ++i)
+ if (buf[ph + i] != 0)
+ goto nospace;
+
+ /* fill in the program header entry */
+ ns = ph + ps;
+ PUT_32BE(ph + PH_TYPE, PT_NOTE);
+ PUT_32BE(ph + PH_OFFSET, ns);
+ PUT_32BE(ph + PH_FILESZ, nnote);
+
+ /* fill in the note area we point to */
+ /* XXX we should probably make this a proper section */
+ PUT_32BE(ns, strlen(arch) + 1);
+ PUT_32BE(ns + 4, N_DESCR * 4);
+ PUT_32BE(ns + 8, 0x1275);
+ strcpy(&buf[ns + 12], arch);
+ ns += 12 + strlen(arch) + 1;
+ for (i = 0; i < N_DESCR; ++i)
+ PUT_32BE(ns + i * 4, descr[i]);
+
+ /* Update the number of program headers */
+ PUT_16BE(E_PHNUM, np + 1);
+
+ /* write back */
+ lseek(fd, (long) 0, SEEK_SET);
+ i = write(fd, buf, n);
+ if (i < 0) {
+ perror("write");
+ exit(1);
+ }
+ if (i < n) {
+ fprintf(stderr, "%s: write truncated\n", av[1]);
+ exit(1);
+ }
+
+ exit(0);
+
+ notelf:
+ fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]);
+ exit(1);
+
+ nospace:
+ fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
+ av[1]);
+ exit(1);
+}
--- /dev/null
+/*
+ * Extract the loadable program segment from an elf file.
+ *
+ * Copyright 1996 Paul Mackerras.
+ */
+#include <stdio.h>
+#include <linux/elf.h>
+
+FILE *fi, *fo;
+char *ni, *no;
+char buf[65536];
+
+void
+rd(void *buf, int len)
+{
+ int nr;
+
+ nr = fread(buf, 1, len, fi);
+ if (nr == len)
+ return;
+ if (ferror(fi))
+ fprintf(stderr, "%s: read error\n", ni);
+ else
+ fprintf(stderr, "%s: short file\n", ni);
+ exit(1);
+}
+
+int
+main(int ac, char **av)
+{
+ unsigned nb, len, i;
+ Elf32_Ehdr eh;
+ Elf32_Phdr ph;
+ unsigned long phoffset, phsize, prevaddr;
+
+ if (ac > 3 || (ac > 1 && av[1][0] == '-')) {
+ fprintf(stderr, "Usage: %s [elf-file [image-file]]\n", av[0]);
+ exit(0);
+ }
+
+ fi = stdin;
+ ni = "(stdin)";
+ fo = stdout;
+ no = "(stdout)";
+
+ if (ac > 1) {
+ ni = av[1];
+ fi = fopen(ni, "rb");
+ if (fi == NULL) {
+ perror(ni);
+ exit(1);
+ }
+ }
+
+ rd(&eh, sizeof(eh));
+ if (eh.e_ident[EI_MAG0] != ELFMAG0
+ || eh.e_ident[EI_MAG1] != ELFMAG1
+ || eh.e_ident[EI_MAG2] != ELFMAG2
+ || eh.e_ident[EI_MAG3] != ELFMAG3) {
+ fprintf(stderr, "%s: not an ELF file\n", ni);
+ exit(1);
+ }
+
+ fseek(fi, eh.e_phoff, 0);
+ phsize = 0;
+ for (i = 0; i < eh.e_phnum; ++i) {
+ rd(&ph, sizeof(ph));
+ if (ph.p_type != PT_LOAD)
+ continue;
+ if (phsize == 0 || prevaddr == 0) {
+ phoffset = ph.p_offset;
+ phsize = ph.p_filesz;
+ } else
+ phsize = ph.p_offset + ph.p_filesz - phoffset;
+ prevaddr = ph.p_vaddr;
+ }
+ if (phsize == 0) {
+ fprintf(stderr, "%s: doesn't have a loadable segment\n", ni);
+ exit(1);
+ }
+
+ if (ac > 2) {
+ no = av[2];
+ fo = fopen(no, "wb");
+ if (fo == NULL) {
+ perror(no);
+ exit(1);
+ }
+ }
+
+ fseek(fi, phoffset, 0);
+ for (len = phsize; len != 0; len -= nb) {
+ nb = len;
+ if (nb > sizeof(buf))
+ nb = sizeof(buf);
+ rd(buf, nb);
+ if (fwrite(buf, 1, nb, fo) != nb) {
+ fprintf(stderr, "%s: write error\n", no);
+ exit(1);
+ }
+ }
+
+ fclose(fo);
+ fclose(fi);
+ exit(0);
+}
--- /dev/null
+ybin
\ No newline at end of file
--- /dev/null
+#! /bin/sh
+
+###############################################################################
+##
+## ofpath: determine OpenFirmware path from unix device node
+## Copyright (C) 2000, 2001 Ethan Benson
+##
+## Portions based on show_of_path.sh:
+##
+## Copyright (C) 2000 Olaf Hering <olh@suse.de>
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+###############################################################################
+
+PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
+PRG="${0##*/}"
+VERSION=1.0.2
+DEBUG=0
+export LC_COLLATE=C
+
+## --version output.
+version()
+{
+echo \
+"$PRG $VERSION
+Written by Ethan Benson
+Portions based on show_of_path.sh written by Olaf Hering
+
+Copyright (C) 2000, 2001 Ethan Benson
+Portions Copyright (C) 2000 Olaf Hering
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+}
+
+## --help output.
+usage()
+{
+echo \
+"Usage: $PRG [OPTION]... FILE
+Find OpenFirmware device path from unix device node.
+
+ --debug print boring junk only useful for debugging
+ -h, --help display this help and exit
+ -V, --version output version information and exit"
+}
+
+## a small seq replacement, seq is not present on boot/rescue floppies.
+smallseq()
+{
+ local v="$1"
+ local n=1
+ echo 1
+ while [ "$v" -gt 1 ] ; do
+ echo "$(($n + 1))"
+ local n="$(($n + 1))"
+ local v="$(($v - 1))"
+ done
+ return 0
+}
+
+## a kludge to replace wc -l, wc is not present on boot/rescue
+## floppies. max file is 145 lines, 3 hosts * 16 devs each * 3 lines
+## per device, + 1 "Attached Devices:" line.
+linecount()
+{
+ if [ $# = 0 ] ; then
+ local file="$(cat)"
+ local v="$file"
+ else
+ local file="$(cat $1)"
+ local v="$file"
+ fi
+
+ if [ -z "$file" ] ; then
+ echo 0
+ return 0
+ fi
+
+ ## use real wc if available
+ if (command -v wc > /dev/null 2>&1) ; then
+ if [ -x `command -v wc` ] ; then
+ lines="$(echo "$file" | wc -l)"
+ if [ $? = 0 ] ; then
+ echo $lines
+ unset lines
+ return 0
+ fi
+ fi
+ fi
+
+ while true ; do
+ for i in `smallseq 145` ; do
+ local b="$(echo "$file" | tail -n $i)"
+ if [ "$v" = "$b" ] ; then
+ echo "$i"
+ break 2
+ fi
+ done
+ done
+ return 0
+}
+
+## small tr replacment which handles a specific need of this script.
+smalltr()
+{
+ case "$1" in
+ a) echo 1 ;; b) echo 2 ;; c) echo 3 ;; d) echo 4 ;; e) echo 5 ;; f) echo 6 ;;
+ g) echo 7 ;; h) echo 8 ;; i) echo 9 ;; j) echo 10 ;; k) echo 11 ;; l) echo 12 ;;
+ m) echo 13 ;; n) echo 14 ;; o) echo 15 ;; p) echo 16 ;;
+ 1) echo a ;; 2) echo b ;; 3) echo c ;; 4) echo d ;; 5) echo e ;;
+ 6) echo f ;; 7) echo g ;; 8) echo h ;; 9) echo i ;; 10) echo j ;;
+ 11) echo k ;; 12) echo l ;; 13) echo m ;; 14) echo n ;; 15) echo o ;;
+ 16) echo p ;;
+ esac
+ return 0
+}
+
+## replacment for grep -l which is not supported by busybox grep.
+## echo $(cat..) hack needed because busybox grep barfs with `line too
+## long' when fed /proc files. the for loop is needed since busybox
+## grep seems to have somewhat broken regexp support.
+## usage: lgrep filename regexp regexp ...
+lgrep()
+{
+ local f="$1"
+ shift
+ for i in "$@" ; do
+ echo "$(cat "$f")" | grep -q "$i" && echo "$f" && break
+ done
+ return 0
+}
+
+## a function to print relevant scsi host path when there is more then
+## one. this function also takes care of stripping off the trailing
+## /compatible.
+printhost()
+{
+ case "$1" in
+ 1)
+ echo "${2%/*}"
+ ;;
+ 2)
+ echo "${3%/*}"
+ ;;
+ 3)
+ echo "${4%/*}"
+ ;;
+ 4)
+ echo "${5%/*}"
+ ;;
+ esac
+ return 0
+}
+
+## this finds information we need on both newworld and oldworld macs.
+## mainly what scsi host a disk is attached to.
+scsiinfo()
+{
+ ## see if system has scsi at all
+ if [ ! -f /proc/scsi/scsi ] ; then
+ echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
+ return 1
+ fi
+
+ ## first we have to figure out the SCSI ID, have to do that
+ ## anyway [to] find the attached scsi disks = "Direct-Access" and
+ ## stop at sda=1 sdb=2 or whatever count in 3 lines steps
+
+ ## get last letter of device node, ie sda -> a
+ SUBNODE=${DEVNODE##*sd}
+
+ ## turn SUBNODE above into a number starting at 1, ie a -> 1
+ SUBDEV="$(smalltr $SUBNODE)"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: SUBNODE=$SUBNODE SUBDEV=$SUBDEV"
+
+ DEVCOUNT=0
+
+ ## copy scsi file into a variable removing "Attached Devices"
+ ## which is the first line. this avoids a lot of
+ ## [incmopatible] crap later, and improves readability.
+
+ ## find number of lines once and recycle that number, to save
+ ## some time (linecount is a bit slow). subtract one line
+ ## to scrap Attached Devices:
+
+ SCSILINES="$(($(linecount /proc/scsi/scsi) - 1))"
+
+ if [ "$SUBDEV" -gt "$(cat /proc/scsi/scsi | grep Direct-Access | linecount)" ] ; then
+ echo 1>&2 "$PRG: /dev/$DEVNODE: Device not configured"
+ return 1
+ fi
+
+ PROCSCSI="$(cat /proc/scsi/scsi | tail -n $SCSILINES)"
+
+ for i in $(smallseq $(($SCSILINES / 3))) ; do
+
+ ## put every scsi device into one single line
+ DEVINFO="$(echo "$PROCSCSI" | head -n $(($i * 3)) | tail -n 3)"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVINFO=$DEVINFO"
+
+ ## cut the type field, expect "Direct-Access" later.
+ DEVTYPE="$(v=$(echo ${DEVINFO##*Type: }) ; echo ${v%% *})"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVTYPE=$DEVTYPE"
+
+ ## get the device id.
+ DEVID="$(v=$(echo ${DEVINFO##*Id: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVID=$DEVID"
+
+ ## get the scsi host id.
+ DEVHOST="$(v=$(echo ${DEVINFO##*Host: scsi}) ; echo ${v%% *})"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVHOST=$DEVHOST"
+
+ if [ "$DEVTYPE" = "Direct-Access" ] ; then
+ DEVCOUNT="$(($DEVCOUNT + 1))"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVCOUNT=$DEVCOUNT"
+ if [ "$SUBDEV" = "$DEVCOUNT" ] ; then
+ DEVICE_HOST=$DEVHOST
+ DEVICE_ID=$DEVID
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVICE_HOST=$DEVICE_HOST"
+ break
+ fi
+ fi
+ done
+
+ ## figure out what the scsi driver is, it is /proc/scsi/dirname.
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: DEVICE_HOST=$DEVICE_HOST"
+ SCSI_DRIVER="$(x=`ls /proc/scsi/*/$DEVICE_HOST 2>/dev/null | cat` ; y=`echo ${x##*proc/scsi/}` ; echo ${y%%/*})"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: SCSI_DRIVER=$SCSI_DRIVER"
+
+ ## figure out which host we found.
+ SCSI_HOSTNUMBER="$(v=`ls /proc/scsi/$SCSI_DRIVER/* 2>/dev/null | cat | grep -n "$DEVICE_HOST\>"` ; echo ${v%%:*})"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: SCSI_HOSTNUMBER=$SCSI_HOSTNUMBER"
+
+ return 0
+}
+
+## generic function that can find OF device paths for scsi devices,
+## must be run after scsiinfo().
+scsi_ofpath()
+{
+ case "$SCSI_DRIVER" in
+ aic7xxx)
+ HOST_LIST="$(for i in `find /proc/device-tree -name compatible` ; do
+ lgrep "$i" "^ADPT" "^pci900[45]" "^pciclass,01000" ; done)"
+ DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
+ echo "${DEVICE_PATH##*device-tree}/@$DEVICE_ID:$PARTITION"
+ ;;
+ sym53c8xx)
+ HOST_LIST="$(for i in `find /proc/device-tree -name compatible` ; do
+ lgrep "$i" "^Symbios" "^pci1000" "^pciclass,01000" ; done)"
+ DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
+ echo "${DEVICE_PATH##*device-tree}/@$DEVICE_ID:$PARTITION"
+ ;;
+ mesh)
+ HOST_LIST="$(for i in `find /proc/device-tree -name compatible` ; do
+ lgrep "$i" "mesh" ; done)"
+ DEVICE_PATH="$(printhost $SCSI_HOSTNUMBER $HOST_LIST)"
+ echo "${DEVICE_PATH##*device-tree}/@$DEVICE_ID:$PARTITION"
+ ;;
+ *)
+ echo 1>&2 "$PRG: Driver: $SCSI_DRIVER is not supported"
+ return 1
+ ;;
+ esac
+ return 0
+}
+
+## figure out the OpenFirmware device path for newworld macs.
+## sd* scsi disks , hd* ide disks.
+newworld()
+{
+ case "$DEVNODE" in
+ sd*)
+ if ls -l /proc/device-tree | grep -q ^lr ; then
+ true
+ else
+ echo 1>&2 "$PRG: /proc/device-tree is broken. Do not use BootX to boot, use yaboot."
+ echo 1>&2 "$PRG: The yaboot FAQ can be found here: http://www.alaska.net/~erbenson/doc"
+ return 1
+ fi
+
+ ## use common scsiinfo function to get info we need.
+ scsiinfo || return 1
+
+ ## now we have the data for /@$DEVID:$PARTITION
+ ## find the actual OF path.
+ scsi_ofpath || return 1
+ ;;
+ hda*)
+ local CDROM="$(grep "^drive name:" /proc/sys/dev/cdrom/info 2> /dev/null | grep hda)"
+ if [ -z "$CDROM" ] ; then
+ echo "hd:$PARTITION"
+ else
+ echo "cd:$PARTITION"
+ fi
+ ;;
+ hdb*)
+ local CDROM="$(grep "^drive name:" /proc/sys/dev/cdrom/info 2> /dev/null | grep hdb)"
+ if [ -z "$CDROM" ] ; then
+ echo "ultra1:$PARTITION"
+ else
+ echo "cd:$PARTITION"
+ fi
+ ;;
+ hd*)
+ local CDROM="$(grep "^drive name:" /proc/sys/dev/cdrom/info 2> /dev/null | grep $DEVNODE)"
+ if [ -z "$CDROM" ] ; then
+ echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
+ return 1
+ else
+ echo "cd:$PARTITION"
+ fi
+ ;;
+ *)
+ echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
+ return 1
+ ;;
+ esac
+ return 0
+}
+
+oldworld()
+{
+ ## for some reason 2.4 kernels put OF aliases in aliases@0/ instead of plain aliases/
+ if [ -d "/proc/device-tree/aliases" ] ; then
+ local ALIASES="aliases"
+ elif [ -d "/proc/device-tree/aliases@0" ] ; then
+ local ALIASES="aliases@0"
+ else
+ echo 1>&2 "$PRG: Cannot find OpenFirmware aliases directory in /proc/device-tree/"
+ return 1
+ fi
+
+ local MODEL="$(cat /proc/device-tree/compatible)"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: Oldworld subarch: $MODEL"
+
+ case "$MODEL" in
+ AAPL,7300*|AAPL,7500*|AAPL,8500*|AAPL,9500*|AAPL,\?\?\?\?*)
+ case "$DEVNODE" in
+ sd*)
+ scsiinfo || return 1
+ case "$SCSI_DRIVER" in
+ mesh)
+ echo $(cat /proc/device-tree/$ALIASES/scsi-int)/sd\@$DEVICE_ID:$PARTITION
+ ;;
+ 53c94)
+ echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
+ ;;
+ *)
+ echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
+ return 1
+ ;;
+ esac
+ ;;
+ *)
+ echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
+ return 1
+ ;;
+ esac
+ ;;
+ AAPL,e407*)
+ case "$DEVNODE" in
+ sd*)
+ scsiinfo || return 1
+ case "$SCSI_DRIVER" in
+ mesh)
+ echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
+ ;;
+ *)
+ echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
+ return 1
+ ;;
+ esac
+ ;;
+ hda*)
+ echo $(cat /proc/device-tree/$ALIASES/ata)/ATA-Disk\@0:$PARTITION
+ ;;
+ hdb*)
+ echo $(cat /proc/device-tree/$ALIASES/ata)/ATA-Disk\@1:$PARTITION
+ ;;
+ hd*)
+ echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
+ ;;
+ esac
+ ;;
+ AAPL,e826*)
+ case "$DEVNODE" in
+ sd*)
+ scsiinfo || return 1
+ case "$SCSI_DRIVER" in
+ mesh)
+ echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
+ ;;
+ *)
+ echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
+ return 1
+ ;;
+ esac
+ ;;
+ hda*)
+ echo $(cat /proc/device-tree/$ALIASES/ata)/ata-disk\@0:$PARTITION
+ ;;
+ hdb*)
+ echo $(cat /proc/device-tree/$ALIASES/ata)/ata-disk\@1:$PARTITION
+ ;;
+ hd*)
+ echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
+ ;;
+ esac
+ ;;
+ AAPL,Gossamer*|AAPL,PowerMac\ G3*)
+ case "$DEVNODE" in
+ sd*)
+ scsiinfo || return 1
+ case "$SCSI_DRIVER" in
+ mesh)
+ echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITION
+ ;;
+ *)
+ echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
+ return 1
+ ;;
+ esac
+ ;;
+ hda*)
+ echo $(cat /proc/device-tree/$ALIASES/ide0)/ata-disk\@0:$PARTITION
+ ;;
+ hdb*)
+ echo $(cat /proc/device-tree/$ALIASES/ide0)/ata-disk\@1:$PARTITION
+ ;;
+ hdc*)
+ echo $(cat /proc/device-tree/$ALIASES/ide1)/ata-disk\@0:$PARTITION
+ ;;
+ hdd*)
+ echo $(cat /proc/device-tree/$ALIASES/ide1)/ata-disk\@1:$PARTITION
+ ;;
+ hd*)
+ echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
+ ;;
+ esac
+ ;;
+ AAPL,PowerBook1998*)
+ if [ -f /proc/device-tree/$ALIASES/ata0 ] ; then
+ local ATA0=ata0
+ else
+ local ATA0=ide0
+ fi
+ if [ -f /proc/device-tree/$ALIASES/ata1 ] ; then
+ local ATA1=ata1
+ else
+ local ATA1=bay-ata1
+ fi
+ case "$DEVNODE" in
+ sd*)
+ scsiinfo || return 1
+ case "$SCSI_DRIVER" in
+ mesh)
+ echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITON
+ ;;
+ *)
+ echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
+ return 1
+ ;;
+ esac
+ ;;
+ hda*)
+ echo $(cat /proc/device-tree/$ALIASES/$ATA0)/ata-disk\@0:$PARTITION
+ ;;
+ hdb*)
+ echo $(cat /proc/device-tree/$ALIASES/$ATA0)/ata-disk\@1:$PARTITION
+ ;;
+ hdc*)
+ echo $(cat /proc/device-tree/$ALIASES/$ATA1)/atapi-disk\@0:$PARTITION
+ ;;
+ hdd*)
+ echo $(cat /proc/device-tree/$ALIASES/$ATA1)/atapi-disk\@1:$PARTITION
+ ;;
+ *)
+ echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
+ return 1
+ ;;
+ esac
+ ;;
+ AAPL,3400/2400*)
+ case "$DEVNODE" in
+ sd*)
+ scsiinfo || return 1
+ case "$SCSI_DRIVER" in
+ mesh)
+ echo $(cat /proc/device-tree/$ALIASES/scsi-int)/sd\@$DEVICE_ID:$PARTITON
+ ;;
+ 53c94)
+ echo $(cat /proc/device-tree/$ALIASES/scsi)/sd\@$DEVICE_ID:$PARTITON
+ ;;
+ *)
+ echo 1>&2 "$PRG: Driver $SCSI_DRIVER is not supported"
+ return 1
+ ;;
+ esac
+ ;;
+ hda*)
+ echo $(cat /proc/device-tree/$ALIASES/ata0)/ata-disk\@0:$PARTITION
+ ;;
+ hdb*)
+ echo $(cat /proc/device-tree/$ALIASES/ata0)/ata-disk\@1:$PARTITION
+ ;;
+ hdc*)
+ echo $(cat /proc/device-tree/$ALIASES/ata1)/atapi-disk\@0:$PARTITION
+ ;;
+ hdd*)
+ echo $(cat /proc/device-tree/$ALIASES/ata1)/atapi-disk\@1:$PARTITION
+ ;;
+ hde*)
+ echo $(cat /proc/device-tree/$ALIASES/ata2):$PARTITION
+ ;;
+ hdf*)
+ echo $(cat /proc/device-tree/$ALIASES/ata3):$PARTITION
+ ;;
+ *)
+ echo 1>&2 "$PRG: Unsupported device: /dev/$DEVNODE"
+ return 1
+ ;;
+ esac
+ ;;
+ *)
+ echo 1>&2 "$PRG: This machine is not supported: $MODEL"
+ return 1
+ ;;
+ esac
+ return 0
+}
+
+## find OpenFirmware device path for IBM CHRP hardware (scsi only)
+chrp()
+{
+ case "$DEVNODE" in
+ sd*)
+ if ls -l /proc/device-tree | grep -q ^lr ; then
+ true
+ else
+ echo 1>&2 "$PRG: /proc/device-tree is broken."
+ return 1
+ fi
+
+ ## use common scsiinfo function to get info we need.
+ scsiinfo || return 1
+
+ ## now we have the data for /@$DEVID:$PARTITION
+ ## find the actual OF path.
+ scsi_ofpath || return 1
+ ;;
+ *)
+ echo 1>&2 "$PRG: Device: /dev/$DEVNODE is not supported"
+ return 1
+ ;;
+ esac
+ return 0
+}
+
+## If we get lame devfs name, we need to make it foad
+ckdevfs()
+{
+ case "$1" in
+ /dev/ide/*|/dev/scsi/*|/dev/discs/*)
+ return 0
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+}
+
+## convert devfs names into normal short ones, written by Tom Rini.
+fixdevfs()
+{
+ ## get partition number, if any
+ local PARTNUM="${1##*[a-z]}"
+ ## Find the bus type.
+ local TYPE="$(v=${1#/dev/} ; echo ${v%/host*})"
+ ## Find the host number.
+ local HOST="$(v=${1#/dev/*/host} ; echo ${v%/bus*})"
+ ## Find the bus number.
+ local BUS="$(v=${1#/dev/*/bus} ; echo ${v%/tar*})"
+ ## Find the target.
+ local TARGET="$(v=${1#/dev/*/target} ; echo ${v%/lun*})"
+
+ case "$TYPE" in
+ ide)
+ case "$HOST" in
+ 0)
+ case "$TARGET" in
+ 0)
+ local DEV=hda
+ ;;
+ 1)
+ local DEV=hdb
+ ;;
+ esac
+ ;;
+ 1)
+ case "$TARGET" in
+ 0)
+ local DEV=hdc
+ ;;
+ 1)
+ local DEV=hdd
+ ;;
+ esac
+ ;;
+ *)
+ echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs."
+ return 1
+ esac
+ local DEV="${DEV}${PARTNUM}"
+ echo "/dev/$DEV"
+ return 0
+ ;;
+ scsi)
+ local LUN="$(v=${1#/dev/*/lun} ; echo ${v%/*})"
+
+ ## In this case, we need to figure out what number our device is
+ local DEVCOUNT=0
+
+ ## copy scsi file into a variable removing "Attached Devices"
+ ## which is the first line. this avoids a lot of
+ ## [incmopatible] crap later, and improves readability.
+
+ ## find number of lines once and recycle that number, to save
+ ## some time (linecount is a bit slow). subtract one line
+ ## to scrap Attached Devices:
+
+ local SCSILINES="$(($(linecount /proc/scsi/scsi) - 1))"
+ local PROCSCSI="$(cat /proc/scsi/scsi | tail -n $SCSILINES)"
+
+ for i in $(smallseq $(($SCSILINES / 3))) ; do
+
+ ## put every scsi device into one single line
+ local DEVINFO="$(echo "$PROCSCSI" | head -n $(($i * 3)) | tail -n 3)"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVINFO=$DEVINFO"
+
+ ## cut the type field, expect "Direct-Access" later.
+ local DEVTYPE="$(v=$(echo ${DEVINFO##*Type: }) ; echo ${v%% *})"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVTYPE=$DEVTYPE"
+
+ if [ "$DEVTYPE" = "Direct-Access" ] ; then
+ ## Lets find out some more information
+ ## get the device id.
+ local DEVID="$(v=$(echo ${DEVINFO##*Id: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVID=$DEVID"
+
+ ## get the device lun.
+ local DEVLUN="$(v=$(echo ${DEVINFO##*Lun: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVLUN=$DEVLUN"
+
+ ## get the device channel.
+ local DEVCHAN="$(v=$(echo ${DEVINFO##*Channel: }) ; n=$(echo ${v%% *}) ; echo ${n#*0})"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVCHAN=$DEVCHAN"
+
+ ## get the scsi host id.
+ local DEVHOST="$(v=$(echo ${DEVINFO##*Host: scsi}) ; echo ${v%% *})"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVHOST=$DEVHOST"
+
+ local DEVCOUNT="$(($DEVCOUNT + 1))"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: fixdevfs: DEVCOUNT=$DEVCOUNT"
+ if [ "$DEVHOST" = "$HOST" -a "$DEVCHAN" = "$BUS" -a \
+ "$DEVID" = "$TARGET" -a "$DEVLUN" = "$LUN" ] ; then
+ local DEV="sd$(smalltr $DEVCOUNT)${PARTNUM}"
+ echo "/dev/$DEV"
+ return 0
+ fi
+ fi
+ done
+ echo 1>&2 "$PRG: $1: Unable to translate this device, try again without devfs."
+ return 1
+ ;;
+ *)
+ echo 1>&2 "$PRG: Unknown bus $TYPE"
+ return 1
+ ;;
+ esac
+ ## we should never get here
+ return 1
+}
+
+## make sure that find, head and tail can be found. otherwise the
+## script will silently give bogus paths. these are the only /usr/*
+## utilities this script depends on.
+checkutils()
+{
+ if command -v find > /dev/null 2>&1 ; then
+ [ -x `command -v find` ] || FAIL=1 ; else FAIL=1 ; fi
+ if command -v head > /dev/null 2>&1 ; then
+ [ -x `command -v head` ] || FAIL=1 ; else FAIL=1 ; fi
+ if command -v tail > /dev/null 2>&1 ; then
+ [ -x `command -v tail` ] || FAIL=1 ; else FAIL=1 ; fi
+
+ if [ "$FAIL" = 1 ] ; then
+ echo 1>&2 "$PRG: \`find', \`head', or \`tail' could not be found, aborting."
+ return 1
+ else
+ return 0
+ fi
+}
+
+## parse command line switches.
+if [ $# != 0 ] ; then
+ while true ; do
+ case "$1" in
+ -V|--version)
+ version
+ exit 0
+ ;;
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ --debug)
+ DEBUG=1
+ shift
+ ;;
+ -*)
+ echo 1>&2 "$PRG: unrecognized option \`$1'"
+ echo 1>&2 "$PRG: Try \`$PRG --help' for more information."
+ exit 1
+ ;;
+ "")
+ echo 1>&2 "$PRG: You must specify a filename"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ ;;
+ *)
+ device="$1"
+ break
+ ;;
+ esac
+ done
+else
+ echo 1>&2 "$PRG: You must specify a /dev device"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+fi
+
+## check that FILE is a block device and exists.
+if [ ! -e "$device" ] ; then
+ echo 1>&2 "$PRG: $device: No such file or directory"
+ exit 1
+elif [ ! -b "$device" ] ; then
+ echo 1>&2 "$PRG: $device is not a block device"
+ exit 1
+fi
+
+## check that we are running on a GNU/Linux system, OSX/BSD does not
+## have the same /proc stuff
+if [ `uname -s` != Linux ] ; then
+ echo 1>&2 "$PRG: This utility will only work with GNU/Linux"
+ exit 1
+fi
+
+## check for ppc, i think uname -m is safe for this...
+if [ `uname -m` != ppc ] ; then
+ echo 1>&2 "$PRG: This utility will only work on PowerPC hardware"
+ exit 1
+fi
+
+## ofpath cannot live without procfs
+if [ ! -f /proc/uptime ] ; then
+ echo 1>&2 "$PRG: This utility requires the /proc filesystem"
+ exit 1
+fi
+
+## check for retarded devfs names and tell them to foad.
+if ckdevfs "$device" ; then
+ device="$(fixdevfs $device)" || exit 1
+fi
+
+## check for newworld mac. use cat hack due to /proc wierdness.
+if [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:[ ]})" = NewWorld ] ; then
+ SUBARCH=NewWorld
+elif [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:[ ]})" = OldWorld ] ; then
+ SUBARCH=OldWorld
+elif (cat /proc/cpuinfo 2>/dev/null | grep ^motherboard | grep -q AAPL) ; then
+ SUBARCH=OldWorld
+elif (cat /proc/cpuinfo 2> /dev/null | grep ^machine | grep -q 'CHRP IBM') ; then
+ SUBARCH=CHRP
+else
+ echo 1>&2 "$PRG: This machine is not yet supported"
+ exit 1
+fi
+
+## make sure /proc/device-tree exists
+if [ ! -d /proc/device-tree ] ; then
+ echo 1>&2 "$PRG: /proc/device-tree does not exist"
+ echo 1>&2 "$PRG: Make sure you compiled your kernel with CONFIG_PROC_DEVICETREE=y"
+ exit 1
+fi
+
+## make sure we have what we need.
+checkutils || exit 1
+
+## get the base device node and scrap /dev/ ie /dev/hda2 -> hda
+DEVICE="${device##*/}"
+DEVNODE="${DEVICE%%[0-9]*}"
+PARTITION="${DEVICE##*[a-z]}"
+
+## use appropriate search for right sub arch.
+case "$SUBARCH" in
+ NewWorld)
+ newworld || exit 1
+ ;;
+ OldWorld)
+ oldworld || exit 1
+ ;;
+ CHRP)
+ chrp || exit 1
+ ;;
+esac
+
+exit 0
--- /dev/null
+#! /bin/sh
+
+###############################################################################
+##
+## yabootconfig generates a simple /etc/yaboot.conf
+## Copyright (C) 2001 Ethan Benson
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+###############################################################################
+
+PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
+## allow to run out of /target in boot-floppies
+if [ -n "$PATH_PREFIX" ] ; then
+ PATH="${PATH}:${PATH_PREFIX}/sbin:${PATH_PREFIX}/bin:${PATH_PREFIX}/usr/sbin:${PATH_PREFIX}/usr/bin:${PATH_PREFIX}/usr/local/sbin:${PATH_PREFIX}/usr/local/bin"
+fi
+PRG="${0##*/}"
+VERSION=1.0.3
+CHROOT=/
+## $CONFIG is relative to $CHROOT
+CONFIG=etc/yaboot.conf
+NOINSTALL=0
+QUIET=0
+SIGINT="$PRG: Interrupt caught ... exiting"
+export LC_COLLATE=C
+
+## catch signals, clean up temporary file
+trap "cleanup" 0
+trap "exit 129" 1
+trap "echo 1>&2 $SIGINT ; exit 130" 2
+trap "exit 131" 3
+trap "exit 143" 15
+
+## check for printf, use it if possible otherwise fall back on
+## unreliable echo -e -n ("SUS" says echo shall support no switches)
+if [ "$(printf printf_test 2>/dev/null)" = printf_test ] ; then
+ PRINTF=printf
+else
+ PRINTF="echo -e -n"
+fi
+
+## make sure echo is not lame if we must use it.
+if [ "$PRINTF" != printf ] ; then
+ if [ "$(echo -e -n echo_test)" != "echo_test" ] ; then
+ echo 1>&2 "$PRG: printf unavailable and echo is broken, sorry."
+ exit 1
+ fi
+fi
+
+## make fake `id' if its missing, outputs 0 since if its missing we
+## are probably running on boot floppies and thus are root.
+if (command -v id > /dev/null 2>&1) ; then
+ true
+else
+ id()
+ {
+ echo 0
+ }
+fi
+
+## --version output
+version()
+{
+echo \
+"$PRG $VERSION
+Written by Ethan Benson
+
+Copyright (C) 2001 Ethan Benson
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+}
+
+## --help output.
+usage()
+{
+echo \
+"Usage: $PRG [OPTION]...
+Generate a working /etc/yaboot.conf.
+
+ -t, --chroot set root directory $PRG should work from
+ -r, --root set root partition, Example: /dev/hda3
+ default: determined from {chroot}/etc/fstab
+ -b, --boot set bootstrap partition, Example: /dev/hda2
+ default: first type: Apple_Bootstrap partition
+ --kernel-args add an append= line with specified arguments
+ -q, --quiet don't ask any questions/confirmation
+ --noinstall don't automatically run mkofboot
+ -h, --help display this help and exit
+ -V, --version output version information and exit"
+}
+
+confirm()
+{
+ $PRINTF \
+"yaboot is the Linux Loader for PowerPC. $PRG sets up your system to boot directly
+from your hard disk, without the need for a boot CD, floppy or a network boot.\n"
+[ "$NOINSTALL" = 0 ] && $PRINTF "Install yaboot bootstrap on $BOOT to boot Linux from $ROOT? [Yes] "
+[ "$NOINSTALL" = 1 ] && $PRINTF "Create simple ${CHROOT}${CONFIG} to boot Linux from $ROOT? [Yes] "
+ read ans
+ case "$ans" in
+ Y|y|Yes|yes|YES|"")
+ echo "Creating a simple ${CHROOT}${CONFIG}..."
+ return 0
+ ;;
+ *)
+ if [ "$NOINSTALL" = 0 ] ; then
+ $PRINTF "Create simple ${CHROOT}${CONFIG} without installing the bootstrap? [Yes] "
+ read ans
+ case "$ans" in
+ Y|y|Yes|yes|YES|"")
+ NOINSTALL=1
+ echo 1>&2 "Creating a simple ${CHROOT}${CONFIG}..."
+ return 0
+ ;;
+ *)
+ echo "OK, quitting"
+ return 1
+ ;;
+ esac
+ else
+ echo "OK, quitting"
+ return 1
+ fi
+ ;;
+ esac
+}
+
+## find out whether we have mac-fdisk or pdisk (they work the same)
+ckmacfdisk()
+{
+ if (command -v mac-fdisk > /dev/null 2>&1) ; then
+ FDISK=mac-fdisk
+ elif (command -v pdisk > /dev/null 2>&1) ; then
+ FDISK=pdisk
+ else
+ echo 1>&2 "$PRG: Unable to locate mac-fdisk"
+ return 1
+ fi
+
+ if [ ! -x `command -v $FDISK` 2> /dev/null ] ; then
+ echo 1>&2 "$PRG: `command -v $FDISK`: Permission denied"
+ return 1
+ fi
+ return 0
+}
+
+## find out if we have ddisk or fdisk (fdisk for dos labels) debian
+## uses both names
+ckfdisk()
+{
+ if (command -v ddisk > /dev/null 2>&1) ; then
+ FDISK=ddisk
+ elif (command -v fdisk > /dev/null 2>&1) ; then
+ FDISK=fdisk
+ else
+ echo 1>&2 "$PRG: Unable to locate fdisk"
+ return 1
+ fi
+
+ if [ ! -x `command -v $FDISK` 2> /dev/null ] ; then
+ echo 1>&2 "$PRG: `command -v $FDISK`: Permission denied"
+ return 1
+ fi
+ return 0
+}
+
+## find bootstrap partition, supports IBM CHRP with msdos disklabels
+findbootblock()
+{
+ ## mac partition table magic == ER
+ if [ "$(dd if="$DISK" bs=2 count=1 2> /dev/null)" = ER ] ; then
+ ckmacfdisk || return 1
+ if [ "$FDISK" = pdisk ] ; then
+ ## handle braindamaged pdisk
+ BOOT="$(v=`$FDISK -l "$DISK" 2>/dev/null | grep '\<Apple_Bootstrap\>'` ; echo ${v%%:*})"
+ if [ -n "$BOOT" ] ; then
+ BOOT="${DISK}${BOOT}"
+ fi
+ else
+ BOOT="$(v=`$FDISK -l "$DISK" 2>/dev/null | grep '\<Apple_Bootstrap\>'` ; echo ${v%%[ ]*})"
+ fi
+ if [ -z "$BOOT" ] ; then
+ echo 1>&2 "$PRG: Unable to locate bootstrap partition on $DISK..."
+ echo 1>&2 "$PRG: You must create an 800K type: Apple_Bootstrap partition to make the disk bootable"
+ return 1
+ fi
+ else
+ ckfdisk || return 1
+ BOOT="$(v=`$FDISK -l "$DISK" 2>/dev/null | grep '\<PPC PReP Boot\>'` ; echo ${v%%[ ]*})"
+ if [ -z "$BOOT" ] ; then
+ echo 1>&2 "$PRG: Unable to locate bootstrap partition on $DISK..."
+ echo 1>&2 "$PRG: You must create an 800K type: 0x41 PPC PReP Boot partition to make the disk bootable"
+ return 1
+ fi
+ fi
+ return 0
+}
+
+## if readlink is missing use a kludge
+if (command -v readlink > /dev/null 2>&1) ; then
+ true
+else
+ readlink()
+ {
+ SYMTARGET="$(v=`ls -l "$2" 2>/dev/null` ; echo ${v##*> })"
+ if [ -n "$SYMTARGET" ] ; then
+ echo "$SYMTARGET"
+ return 0
+ else
+ return 1
+ fi
+ }
+fi
+
+## we have to do some things differently with a retarded devfs name.
+ckdevfs()
+{
+ case "$1" in
+ /dev/ide/*|/dev/scsi/*|/dev/discs/*)
+ return 0
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+}
+
+cleanup()
+{
+ if [ -n "$TMPCONF" ] ; then rm -f "$TMPCONF" ; fi
+ return 0
+}
+
+##########
+## Main ##
+##########
+
+if [ $# != 0 ] ; then
+ while true ; do
+ case "$1" in
+ -V|--version)
+ version
+ exit 0
+ ;;
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ -t|--chroot)
+ if [ -n "$2" ] ; then
+ CHROOT="$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
+ ;;
+ -b|--boot)
+ if [ -n "$2" ] ; then
+ BOOT="$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
+ ;;
+ -r|--root)
+ if [ -n "$2" ] ; then
+ ROOT="$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"
+ 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
+ ;;
+ --noinstall)
+ NOINSTALL=1
+ shift 1
+ ;;
+ "")
+ break
+ ;;
+ *)
+ echo 1>&2 "$PRG: unrecognized option \`$1'"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ ;;
+ esac
+ done
+fi
+
+if [ `id -u` != 0 ] ; then
+ echo 1>&2 "$PRG: You are not root, go away"
+ exit 1
+fi
+
+## we need /proc because df does
+if [ ! -f /proc/uptime ] ; then
+ echo 1>&2 "$PRG: This utility requires the /proc filesystem"
+ exit 1
+fi
+
+## check that chroot exists
+if [ -d "$CHROOT" ] ; then
+ ## HACK: add trailing / to chroot, otherwise are paths later get b0rked.
+ case "$CHROOT" in
+ */)
+ true
+ ;;
+ *)
+ CHROOT="${CHROOT}/"
+ ;;
+ esac
+elif [ ! -e "$CHROOT" ] ; then
+ echo 1>&2 "$PRG: $CHROOT: No such file or directory"
+ exit 1
+elif [ ! -d "$CHROOT" ] ; then
+ echo 1>&2 "$PRG: $CHROOT: Not a directory"
+ exit 1
+fi
+
+## make sure the chroot is an actual root filesystem
+if [ ! -f "${CHROOT}etc/fstab" ] ; then
+ echo 1>&2 "$PRG: $CHROOT does not appear to be a valid root filesystem"
+ exit 1
+fi
+
+## find / device
+if [ -z "$ROOT" ] ; then
+ ## IMPORTANT! that last substitution is [<space><tab>] thats all ash will grok
+ ROOT="$(v=`grep '[[:blank:]]/[[:blank:]]' ${CHROOT}etc/fstab` ; echo ${v%%[ ]*})"
+ if [ -z "$ROOT" ] ; then
+ echo 1>&2 "$PRG: Could not determine root partition, aborting..."
+ exit 1
+ fi
+fi
+
+## make sure root device exists
+if [ ! -e "$ROOT" ] ; then
+ echo 1>&2 "$PRG: $ROOT: No such file or directory"
+ exit 1
+fi
+
+## find root disk.
+if ckdevfs "$ROOT" ; then
+ DISK="${ROOT%/*}/disc"
+else
+ DISK="${ROOT%%[0-9]*}"
+fi
+if [ -z "$DISK" ] ; then
+ echo 1>&2 "$PRG: Could not determine root disk, aborting..."
+ exit 1
+fi
+
+## make sure main disk exists
+if [ ! -e "$DISK" ] ; then
+ echo 1>&2 "$PRG: $DISK: No such file or directory"
+ exit 1
+fi
+
+## find bootstrap partition
+if [ -z "$BOOT" ] ; then
+ findbootblock || exit 1
+fi
+
+## make sure bootstrap device exists
+if [ ! -e "$BOOT" ] ; then
+ echo 1>&2 "$PRG: $BOOT: No such file or directory"
+ exit 1
+fi
+
+## sanity check
+for i in "$DISK" "$ROOT" "$BOOT" ; do
+ if [ ! -b "$i" ] ; then
+ echo 1>&2 "$PRG: $i: Not a block device"
+ exit 1
+ fi
+done
+
+## unless --quiet ask permission to proceed
+if [ "$QUIET" = 0 ] ; then
+ confirm || exit 2
+fi
+
+## find the kernel in the usual places and (if not --quiet) ask the
+## user if we cannot find one.
+if [ -f "${CHROOT}vmlinux" ] ; then
+ KERNEL="${CHROOT}vmlinux"
+elif [ -f "${CHROOT}boot/vmlinux" ] ; then
+ KERNEL="${CHROOT}boot/vmlinux"
+elif [ -f "${CHROOT}boot/vmlinux-`uname -r`" ] ; then
+ KERNEL="${CHROOT}boot/vmlinux-`uname -r`"
+elif [ -f "${CHROOT}vmlinux-`uname -r`" ] ; then
+ KERNEL="${CHROOT}vmlinux-`uname -r`"
+elif [ "$QUIET" = 0 ] ; then
+ echo 1>&2 "$PRG: Cannot find a kernel, please locate one"
+ while true ; do
+ $PRINTF 1>&2 "Enter path to a kernel image: "
+ read KERN
+ if [ -f "$KERN" ] ; then
+ KERNEL="$KERN"
+ break
+ elif [ ! -e "$KERN" ] ; then
+ echo 1>&2 "$PRG: $KERN: No such file or directory"
+ elif [ -d "$KERN" ] ; then
+ echo 1>&2 "$PRG: $KERN: Is a directory"
+ else
+ echo 1>&2 "$PRG: $KERN: Is not a regular file"
+ fi
+ done
+else
+ echo 1>&2 "$PRG: Cannot find a kernel, aborting..."
+ exit 1
+fi
+
+## get partition number the kernel lives on, and the OF device= name
+## of the whole disk.
+KERNDEV="$(v=`df "$KERNEL" 2> /dev/null | grep ^/dev/` ; echo ${v%%[ ]*})"
+KERNDIR="$(v=`df "$KERNEL" 2> /dev/null | grep ^/dev/` ; echo ${v##*[ ]})"
+LINKDEV="$(v=`df "${KERNEL%/*}/" 2>/dev/null | grep ^/dev/` ; echo ${v%%[ ]*})"
+PARTITION="${KERNDEV##*[a-z]}"
+
+if ckdevfs "$KERNDEV" ; then
+ KERNELDISK="${KERNDEV%/*}/disc"
+else
+ KERNELDISK="${KERNDEV%%[0-9]*}"
+fi
+
+## sanity check
+for i in "$KERNDEV" "$KERNDIR" "$LINKDEV" "$PARTITION" "$KERNELDISK" ; do
+ if [ -z "$i" ] ; then
+ echo 1>&2 "$PRG: Could not determine necessary information, aborting..."
+ exit 1
+ fi
+done
+
+## check for cross device symlink
+if [ -L "$KERNEL" ] ; then
+ if [ "$KERNDEV" != "$LINKDEV" ] ; then
+ echo 1>&2 "$PRG: Warning: Cross device symlink $KERNEL, using it's target instead"
+ KERNEL="$(readlink -f "$KERNEL" 2>/dev/null)"
+ if [ ! -f "$KERNEL" ] ; then
+ echo 1>&2 "$PRG: Unable to canonicalize symlink's target. Do not create cross device symlinks."
+ exit 1
+ fi
+ fi
+fi
+
+## only powermacs appear to need device=
+if (cat /proc/cpuinfo 2>/dev/null | grep -q pmac-generation 2> /dev/null) ; then
+ DEVICE="\ndevice=$(ofpath $KERNELDISK)"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Unable to determine OpenFirmware device name to $KERNELDISK, aborting..."
+ exit 1
+ fi
+fi
+
+## IBM hardware needs fstype=raw for ybin
+if (cat /proc/cpuinfo 2>/dev/null | grep ^machine | grep -q 'CHRP IBM') ; then
+ FSTYPE="\nfstype=raw"
+fi
+
+## 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
+ IMAGE="${KERNEL##*$KERNDIR}"
+else
+ IMAGE="$KERNEL"
+fi
+
+## fix chrooted path
+if [ "$CHROOT" != / ] ; then
+ IMAGE="${IMAGE##*$CHROOT}"
+fi
+
+## fix relative path (caused by chroot path fix)
+case "$IMAGE" in
+ /*)
+ true
+ ;;
+ *)
+ IMAGE="/${IMAGE}"
+ ;;
+esac
+
+## figure out if yaboot is installed in /usr/local or not
+if [ -f /usr/local/lib/yaboot/yaboot ] ; then
+ INSTALL=/usr/local/lib/yaboot/yaboot
+elif [ -f /usr/lib/yaboot/yaboot ] ; then
+ INSTALL=/usr/lib/yaboot/yaboot
+else
+ echo 1>&2 "$PRG: yaboot is not installed correctly"
+ exit 1
+fi
+
+## newworld powermacs need the ofboot first stage loader
+if [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:})" = NewWorld ] ; then
+ if [ -f /usr/local/lib/yaboot/ofboot ] ; then
+ OFBOOT="\nmagicboot=/usr/local/lib/yaboot/ofboot"
+ elif [ -f /usr/lib/yaboot/ofboot ] ; then
+ OFBOOT="\nmagicboot=/usr/lib/yaboot/ofboot"
+ else
+ echo 1>&2 "$PRG: yaboot is not installed correctly"
+ exit 1
+ fi
+fi
+
+## check for properly (read debian) packaged yaboot.
+if [ -d ${CHROOT}usr/share/doc/yaboot/examples ] ; then
+ HEADER="## see also: /usr/share/doc/yaboot/examples for example configurations.\n"
+fi
+
+## setup append line
+if [ -n "$KERNARGS" ] ; then
+ APPEND="\tappend=\"${KERNARGS}\"\n"
+fi
+
+## 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}${FSTYPE:-}${DEVICE:-}
+partition=$PARTITION
+root=$ROOT
+timeout=30
+install=${INSTALL}${OFBOOT:-}\n"
+
+## generate image= section
+IMAGES="
+image=$IMAGE
+\tlabel=Linux
+\tread-only\n${APPEND:-}"
+
+## safely create a tmp file then move it into place after we are sure
+## it was written.
+TMPCONF=`mktemp -q "${CHROOT}${CONFIG}.XXXXXX"`
+if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Unable to write to ${CHROOT}${CONFIG%/*}"
+ exit 1
+fi
+
+$PRINTF "${GLOBAL}${IMAGES}" > "$TMPCONF"
+if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Unable to write temporary file ${TMPCONF}, aborting..."
+ exit 1
+fi
+
+## rotate backups of /etc/yaboot.conf, 3 backups are kept
+if [ -f "${CHROOT}${CONFIG}.old" ] ; then
+ for i in 1 0 ; do
+ if [ -f "${CHROOT}${CONFIG}.old.${i}" ] ; then
+ mv -f "${CHROOT}${CONFIG}.old.$i" "${CHROOT}${CONFIG}.old.$(($i + 1))"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Unable to make backup of existing ${CHROOT}${CONFIG}.old.$i, aborting..."
+ exit 1
+ fi
+ fi
+ done
+
+ mv -f "${CHROOT}${CONFIG}.old" "${CHROOT}${CONFIG}.old.0"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Unable to make backup of existing ${CHROOT}${CONFIG}.old, aborting..."
+ exit 1
+ fi
+fi
+
+## backup /etc/yaboot.conf
+if [ -f "${CHROOT}${CONFIG}" ] ; then
+ mv -f "${CHROOT}${CONFIG}" "${CHROOT}${CONFIG}.old"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Unable to make backup of existing ${CHROOT}${CONFIG}, aborting..."
+ exit 1
+ fi
+fi
+
+## move new config into place
+mv -f "${TMPCONF}" "${CHROOT}${CONFIG}"
+if [ $? != 0 ] ; then
+ echo "$PRG: Unable to write file ${CHROOT}${CONFIG}"
+ exit 1
+else
+ ## nothing sensitive in generated config, comply with debian policy
+ chmod 644 "${CHROOT}${CONFIG}"
+fi
+
+## tell mkofboot where to find the config file if necessary
+if [ "${CHROOT}${CONFIG}" != /etc/yaboot.conf ] ; then
+ YBINARGS="-C ${CHROOT}${CONFIG}"
+fi
+
+## run mkofboot to install the bootstrap, unless --noinstall
+if [ "$NOINSTALL" = 0 ] ; then
+ if (command -v mkofboot 2>&1 > /dev/null) ; then
+ [ "$QUIET" = 0 ] && echo "Running mkofboot to make the disk bootable..."
+ mkofboot -f $YBINARGS || exit 1
+ [ "$QUIET" = 0 ] && echo "Done"
+ else
+ echo 1>&2 "$PRG: yaboot is not installed correctly, not running mkofboot"
+ exit 1
+ fi
+fi
+
+exit 0
--- /dev/null
+#! /bin/sh
+
+###############################################################################
+##
+## ybin (YaBoot INstaller) installs/updates the yaboot bootloader.
+## Copyright (C) 2000, 2001 Ethan Benson
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License
+## as published by the Free Software Foundation; either version 2
+## of the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+###############################################################################
+
+PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
+## allow to run out of /target in boot-floppies
+if [ -n "$PATH_PREFIX" ] ; then
+ PATH="${PATH}:${PATH_PREFIX}/sbin:${PATH_PREFIX}/bin:${PATH_PREFIX}/usr/sbin:${PATH_PREFIX}/usr/bin:${PATH_PREFIX}/usr/local/sbin:${PATH_PREFIX}/usr/local/bin"
+fi
+PRG="${0##*/}"
+SIGINT="$PRG: Interrupt caught ... exiting"
+VERSION=1.3
+DEBUG=0
+VERBOSE=0
+TMP="${TMPDIR:-/tmp}"
+export LC_COLLATE=C
+
+## catch signals, clean up junk in /tmp.
+trap "cleanup" 0
+trap "exit 129" 1
+trap "echo 1>&2 $SIGINT ; exit 130" 2
+trap "exit 131" 3
+trap "exit 143" 15
+
+## allow for non-existent config file, in which case it will be
+## generated from command line arguments.
+if [ -f /etc/yaboot.conf ] ; then
+ CONF=/etc/yaboot.conf
+ bootconf=$CONF
+ ERR=" Error in $CONF:"
+else
+ CONF=/dev/null
+ bootconf=/dev/null
+fi
+
+## define default configuration
+boot=unconfigured
+
+## allow default to work on packaged and non-packaged yaboot.
+## no default for magicboot since it is not required everywhere.
+if [ -f /usr/local/lib/yaboot/yaboot ] ; then
+ install=/usr/local/lib/yaboot/yaboot
+elif [ -f /usr/lib/yaboot/yaboot ] ; then
+ install=/usr/lib/yaboot/yaboot
+fi
+
+## defaults
+usemount=no
+fstype=hfs
+hfstype=tbxi
+hfscreator=UNIX
+bless=yes
+protect=no
+hide=no
+nonvram=0
+defaultos=linux
+brokenosx=no
+cdrom=no
+network=no
+of=no
+fgcolor=white
+bgcolor=black
+
+## yaboot autoconf defaults
+label=Linux
+timeout=40
+image=/vmlinux
+partition=3
+root=/dev/hda3
+device=hd:
+
+## this program behaves differently based on how its called, this
+## ensures that nothing nasty happens if someone makes a bogus
+## symlink.
+case "$PRG" in
+ ybin)
+ ;;
+ mkofboot)
+ ;;
+ *)
+ echo 1>&2 "This program must be called as either \`ybin' or \`mkofboot'"
+ exit 1
+ ;;
+esac
+
+## check for printf, use it if possible otherwise fall back on
+## unreliable echo -e -n ("SUS" says echo shall support no switches)
+if [ "$(printf printf_test 2>/dev/null)" = printf_test ] ; then
+ PRINTF=printf
+else
+ PRINTF="echo -e -n"
+fi
+
+## make fake `id' if its missing, outputs 0 since if its missing we
+## are probably running on boot floppies and thus are root.
+if (command -v id > /dev/null 2>&1) ; then
+ true
+else
+ id()
+ {
+ echo 0
+ }
+fi
+
+## --version output
+version()
+{
+echo \
+"$PRG $VERSION
+Written by Ethan Benson
+
+Copyright (C) 2000, 2001 Ethan Benson
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+}
+
+## --help output.
+usage()
+{
+echo \
+"Usage: $PRG [OPTION]...
+Update/install bootloader onto a bootstrap partition.
+
+ -b, --boot set bootstrap partition device [ -b /dev/hda2 ]
+ -o, --ofboot set bootstrap partition OpenFirmware device
+ default: automatically determined [ -o hd:2 ]
+ -i, --install pathname to the actual bootloader binary
+ default: /usr/{local/}lib/yaboot/yaboot same as
+ install= in config file [ -i bootloader_file ]
+ -C, --config use alternate configuration file (ybin and yaboot)
+ [ -C config_file ]
+ -m, --magicboot pathname to a OpenFirmware magicboot (CHRP) script
+ --filesystem set the filesystem type of the bootstrap partition
+ available options are hfs, msdos, and raw
+ [ --filesystem hfs ] default is hfs
+ --nobless don't bless the root directory, this should only
+ be used if you are using a MacOS boot partition
+ as the bootstrap partition (not recommended)
+ -M, --mount don't use userspace hfsutils to modify the
+ bootstrap instead try and mount the filesystem
+ directly. Note that attributes cannot be set
+ this way and you will have to manually modify
+ OpenFirmware to make your system bootable
+ --protect set the read-only (locked) bit on all bootstrap
+ files
+ --hide set the invisible bit on all bootstrap files
+ this is useful of you don't want them to be
+ visible from MacOS.
+ --nonvram do not update the boot-device variable in nvram.
+ --device yaboot auto configuration: sets the OF boot device
+ default: hd:
+ --partition yaboot auto configuration: sets the partition
+ number of the root partition. default: 3
+ --timeout yaboot auto configuration: sets the time yaboot
+ will wait for user input before booting default
+ image default: 40 (4 seconds)
+ --image yaboot auto configuration: sets the path to the
+ kernel image. default: /vmlinux
+ --label yaboot auto configuration: sets the image label
+ default: Linux
+ --root yaboot auto configuration: sets the root device
+ default: /dev/hda3
+ --force don't ever ask for confirmation
+ -v, --verbose make $PRG more verbose
+ --debug print boring junk only useful for debugging
+ -h, --help display this help and exit
+ -V, --version output version information and exit"
+}
+
+## configuration file parsing. FIXME: need a method which can parse
+## image= sections.
+parseconf()
+{
+case "$1" in
+ str)
+ v=`grep "^$2[\ ,=]" "$CONF"` ; echo "${v#*=}"
+ ;;
+ flag)
+ grep "^$2\>" "$CONF" > /dev/null && echo 0 || echo 1
+ ;;
+ ck)
+ grep "^$2[\ ,=]" "$CONF" > /dev/null && echo 0 || echo 1
+ ;;
+esac
+}
+
+## check for existence of a configuration file, and make sure we have
+## read permission.
+confexist()
+{
+ if [ ! -e "$CONF" ] ; then
+ echo 1>&2 "$PRG: $CONF: No such file or directory"
+ return 1
+ elif [ ! -f "$CONF" ] ; then
+ echo 1>&2 "$PRG: $CONF: Not a regular file"
+ return 1
+ elif [ ! -r "$CONF" ] ; then
+ echo 1>&2 "$PRG: $CONF: Permission denied"
+ return 1
+ else
+ return 0
+ fi
+}
+
+## check to make sure the configuration file is sane and correct.
+## maybe this is an insane ammount of error checking, but I want to
+## make sure (hopfully) nothing unexpected ever happens. and i just
+## like useful errors from programs. every error just marks an error
+## variable so we give the user as much info as possible before we
+## abandon ship.
+checkconf()
+{
+ if [ ! -e "$boot" ] ; then
+ echo 1>&2 "$PRG: $boot: No such file or directory"
+ local CONFERR=1
+ elif [ ! -b "$boot" -a ! -f "$boot" ] ; then
+ echo 1>&2 "$PRG: $boot: Not a regular file or block device"
+ local CONFERR=1
+ elif [ ! -w "$boot" -o ! -r "$boot" ] ; then
+ [ -z "$mntpoint" ] && echo 1>&2 "$PRG: $boot: Permission denied"
+ [ -z "$mntpoint" ] && CONFERR=1
+ fi
+
+ if [ ! -e "$install" ] ; then
+ echo 1>&2 "$PRG: $install: No such file or directory"
+ local CONFERR=1
+ elif [ ! -f "$install" ] ; then
+ echo 1>&2 "$PRG: $bootconf: Not a regular file"
+ local CONFERR=1
+ elif [ ! -r "$install" ] ; then
+ echo 1>&2 "$PRG: $install: Permission denied"
+ local CONFERR=1
+ fi
+
+ if [ "$bootconf" = auto ] ; then
+ true
+ elif [ ! -e "$bootconf" ] ; then
+ echo 1>&2 "$PRG: $bootconf: No such file or directory"
+ local CONFERR=1
+ elif [ ! -f "$bootconf" ] ; then
+ echo 1>&2 "$PRG: $bootconf: Not a regular file"
+ local CONFERR=1
+ elif [ ! -r "$bootconf" ] ; then
+ echo 1>&2 "$PRG: $bootconf: Permission denied"
+ local CONFERR=1
+ fi
+
+ if [ -n "$magicboot" ] ; then
+ if [ ! -e "$magicboot" ] ; then
+ echo 1>&2 "$PRG: $magicboot: No such file or directory"
+ local CONFERR=1
+ elif [ ! -f "$magicboot" ] ; then
+ echo 1>&2 "$PRG: $magicboot: Not a regular file"
+ local CONFERR=1
+ elif [ ! -r "$magicboot" ] ; then
+ echo 1>&2 "$PRG: $magicboot: Permission denied"
+ local CONFERR=1
+ fi
+ fi
+
+ case "$fstype" in
+ hfs|msdos|raw)
+ ;;
+ *)
+ if [ "$ARGFS" = 1 ] ; then
+ echo 1>&2 "$PRG: --filesystem must be either \`hfs', \`msdos', or \`raw'"
+ else
+ echo 1>&2 "$PRG:$ERR \`fstype' must be either \`hfs', \`msdos', or \`raw'"
+ fi
+ local CONFERR=1
+ ;;
+ esac
+
+ ## if we are not using HFS filesystems we don't care about HFS
+ ## specific options.
+ if [ "$fstype" = hfs ] ; then
+ if [ `echo ${#hfstype}` != 4 ] ; then
+ if [ "$ARGTP" = 1 ] ; then
+ echo 1>&2 "$PRG: --type must be 4 characters"
+ else
+ echo 1>&2 "$PRG:$ERR \`hfstype' must be 4 characters"
+ fi
+ local CONFERR=1
+ fi
+
+ if [ `echo ${#hfscreator}` != 4 ] ; then
+ if [ "$ARGCT" = 1 ] ; then
+ echo 1>&2 "$PRG: --creator must be 4 characters"
+ else
+ echo 1>&2 "$PRG:$ERR \`hfscreator' must be 4 characters"
+ fi
+ local CONFERR=1
+ fi
+ fi
+
+ ## some options are not compatible with fstype=raw
+ if [ "$fstype" = raw ] ; then
+ if [ -n "$mntpoint" ] ; then
+ echo 1>&2 "$PRG:$ERR \`mntpoint' is not compatible with fstype=raw"
+ local CONFERR=1
+ fi
+ if [ "$usemount" = yes ] ; then
+ echo 1>&2 "$PRG:$ERR \`usemount' is not compatible with fstype=raw"
+ local CONFERR=1
+ fi
+ if [ -n "$magicboot" ] ; then
+ echo 1>&2 "$PRG:$ERR \`magicboot' scripts cannot be used with fstype=raw"
+ local CONFERR=1
+ fi
+ fi
+
+ if [ -n "$mntpoint" ] ; then
+ ## standard checks
+ if [ ! -e "$mntpoint" ] ; then
+ echo 1>&2 "$PRG: $mntpoint: No such file or directory"
+ local CONFERR=1
+ elif [ ! -d "$mntpoint" ] ; then
+ echo 1>&2 "$PRG: $mntpoint: Not a directory"
+ local CONFERR=1
+ elif [ ! -w "$mntpoint" -o ! -r "$mntpoint" ] ; then
+ echo 1>&2 "$PRG: $mntpoint: Permission denied"
+ local CONFERR=1
+ elif [ ! -O "$mntpoint" -a `id -u` != 0 ] ; then
+ echo 1>&2 "$PRG: $mntpoint: Permission denied (not owner)"
+ local CONFERR=1
+ fi
+
+ ## make sure no embedded spaces exist
+ echo "$mntpoint" | grep -q [[:space:]]
+ if [ $? = 0 ] ; then
+ echo 1>&2 "$PRG:$ERR \`mntpoint=$mntpoint' contains embedded spaces, don't use lame filenames"
+ local CONFERR=1
+ 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"
+ local CONFERR=1
+ else
+ OFDIR="$(v=`df "$mntpoint" 2>/dev/null | grep ^/dev/`; m=${v##*[ ]}; echo "${mntpoint##*$m/}")"
+ fi
+ fi
+
+ if [ "$usemount" = no ] ; then
+ echo 1>&2 "$PRG:$ERR \`mntpoint=' requires \`usemount' be set"
+ local CONFERR=1
+ fi
+ fi
+
+ if [ -n "$magicboot" ] ; then
+ case "$defaultos" in
+ linux|Linux|GNU|Gnu|gnu)
+ defaultos=bootyaboot
+ ;;
+ bootyaboot)
+ ;;
+ bsd)
+ defaultos=bootbsd
+ if [ -z "$bsd" ] ; then
+ echo 1>&2 "$PRG:$ERR no entry for \`bsd' found, but defaultos is set to \`bsd'"
+ local CONFERR=1
+ fi
+ ;;
+ macos)
+ defaultos=bootmacos
+ if [ -z "$macos" ] ; then
+ echo 1>&2 "$PRG:$ERR no entry for \`macos' found, but defaultos is set to \`macos'"
+ local CONFERR=1
+ fi
+ ;;
+ macosx)
+ defaultos=bootmacosx
+ if [ -z "$macosx" ] ; then
+ echo 1>&2 "$PRG:$ERR no entry for \`macosx' found, but defaultos is set to \`macosx'"
+ local CONFERR=1
+ fi
+ ;;
+ darwin)
+ defaultos=bootdarwin
+ if [ -z "$darwin" ] ; then
+ echo 1>&2 "$PRG:$ERR no entry for \`darwin' found, but defaultos is set to \`darwin'"
+ local CONFERR=1
+ fi
+ ;;
+ *)
+ echo 1>&2 "$PRG:$ERR \`defaultos' must be either \`linux', \`bsd', \`macos' or \`macosx'"
+ local CONFERR=1
+ ;;
+ esac
+ fi
+
+ ## nvsetenv requires /proc
+ if [ ! -f /proc/uptime -a "$nonvram" = 0 ] ; then
+ echo 1>&2 "$PRG: /proc filesystem is not mounted, nvram will not be updated"
+ nonvram=1
+ fi
+
+ if [ "$nonvram" = 0 ] ; then
+ ## see if nvsetenv exists and is executable
+ if (command -v nvsetenv > /dev/null 2>&1) ; then
+ [ -x `command -v nvsetenv` ] || MISSING=1 ; else MISSING=1
+ fi
+
+ if [ "$nonvram" = 0 ] ; then
+ ## if nvsetenv exists see if its the old broken version
+ if [ "$MISSING" != 1 ] ; then
+ nvsetenv --version > /dev/null 2>&1 || OLD=1
+ else
+ nonvram=1
+ echo 1>&2 "$PRG: Warning: \`nvsetenv' could not be found, nvram will not be updated"
+ fi
+
+ if [ "$OLD" = 1 ] ; then
+ ## i check this myself to avoid misleading error
+ ## messages. nvsetenv should REALLY support --version.
+ if [ ! -e /dev/nvram ] ; then
+ echo 1>&2 "$PRG: /dev/nvram: No such file or directory"
+ echo 1>&2 "$PRG: Warning: nvram will not be updated"
+ nonvram=1
+ elif [ ! -c /dev/nvram ] ; then
+ echo 1>&2 "$PRG: /dev/nvram: Not a character device"
+ echo 1>&2 "$PRG: Warning: nvram will not be updated"
+ nonvram=1
+ elif [ ! -w /dev/nvram -o ! -r /dev/nvram ] ; then
+ echo 1>&2 "$PRG: /dev/nvram: Permission denied"
+ echo 1>&2 "$PRG: Warning: nvram will not be updated"
+ nonvram=1
+ else
+ nonvram=1
+ echo 1>&2 "$PRG: Warning: Incompatible version of \`nvsetenv', nvram will not be updated"
+ fi
+ fi
+ fi
+
+ if [ -f "$boot" ] ; then
+ echo 1>&2 "$PRG: $boot is a regular file, disabling nvram updating"
+ nonvram=1
+ fi
+ fi
+
+ ## check for newworld mac. use cat hack due to /proc wierdness.
+ ## do not bail if we are on an OldWorld only warn (very loudly).
+ if [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:})" = NewWorld ] ; then
+ true
+ elif [ "$(v=`cat /proc/cpuinfo 2>/dev/null | grep pmac-generation` ; echo ${v##*:})" = OldWorld ] ; then
+ echo 1>&2
+ echo 1>&2 '@@@@@@@@@@@@@@ WARNING!! WARNING!! WARNING!! @@@@@@@@@@@@@@'
+ echo 1>&2 "$PRG: Warning: This is an OldWorld PowerMac, $boot will **NOT** be bootable on this machine"
+ echo 1>&2 "$PRG: Oldworld PowerMacs need to use the quik bootloader, not yaboot"
+ echo 1>&2 '@@@@@@@@@@@@@@ WARNING!! WARNING!! WARNING!! @@@@@@@@@@@@@@'
+ echo 1>&2
+ [ "$nonvram" = 0 ] && echo 1>&2 "$PRG: OldWorld PowerMac, nvram will not be updated"
+ nonvram=1
+ elif (cat /proc/cpuinfo 2>/dev/null | grep ^motherboard | grep -q AAPL) ; then
+ echo 1>&2
+ echo 1>&2 '@@@@@@@@@@@@@@ WARNING!! WARNING!! WARNING!! @@@@@@@@@@@@@@'
+ echo 1>&2 "$PRG: Warning: This is an OldWorld PowerMac, $boot will **NOT** be bootable on this machine"
+ echo 1>&2 "$PRG: Oldworld PowerMacs need to use the quik bootloader, not yaboot"
+ echo 1>&2 '@@@@@@@@@@@@@@ WARNING!! WARNING!! WARNING!! @@@@@@@@@@@@@@'
+ echo 1>&2
+ [ "$nonvram" = 0 ] && echo 1>&2 "$PRG: OldWorld PowerMac, nvram will not be updated"
+ nonvram=1
+ elif (cat /proc/cpuinfo 2> /dev/null | grep ^machine | grep -q 'CHRP IBM') ; then
+ ## IBM hardware does not need nvram update AFAICT
+ nonvram=1
+ ADDNOTE=yes
+ else
+ #echo 1>&2 "$PRG: Warning: Unknown archetecture, $boot may not be bootable on this machine"
+ [ "$nonvram" = 0 ] && echo 1>&2 "$PRG: Warning: Unknown architecture, nvram will not be updated"
+ nonvram=1
+ fi
+
+ ## convert human readable color values from config to proper color
+ ## codes
+ case "$fgcolor" in
+ black) fgc=0 ;; blue) fgc=1 ;; green) fgc=2 ;; cyan) fgc=3 ;;
+ red) fgc=4 ;; purple) fgc=5 ;; brown) fgc=6 ;; light-gray) fgc=7 ;;
+ dark-gray) fgc=8 ;; light-blue) fgc=9 ;; light-green) fgc=a ;;
+ light-cyan) fgc=b ;; light-red) fgc=c ;; light-purple) fgc=d ;;
+ yellow) fgc=e ;; white) fgc=f ;;
+ *)
+ echo 1>&2 "$PRG:$ERR Invalid fgcolor: \`$fgcolor'"
+ local CONFERR=1
+ ;;
+ esac
+ case "$bgcolor" in
+ black) bgc=0 ;; blue) bgc=1 ;; green) bgc=2 ;; cyan) bgc=3 ;;
+ red) bgc=4 ;; purple) bgc=5 ;; brown) bgc=6 ;; light-gray) bgc=7 ;;
+ dark-gray) bgc=8 ;; light-blue) bgc=9 ;; light-green) bgc=a ;;
+ light-cyan) bgc=b ;; light-red) bgc=c ;; light-purple) bgc=d ;;
+ yellow) bgc=e ;; white) bgc=f ;;
+ *)
+ echo 1>&2 "$PRG:$ERR Invalid bgcolor: \`$bgcolor'"
+ local CONFERR=1
+ ;;
+ esac
+
+ ## if delay is not set use yaboot's timeout
+ if [ -z "$delay" ] ; then
+ delay="$(($timeout / 10))"
+ fi
+
+ if [ "$CONFERR" = 1 ] ; then
+ return 1
+ else
+ return 0
+ fi
+}
+
+
+## if readlink is missing use a kludge
+if (command -v readlink > /dev/null 2>&1) ; then
+ true
+else
+ readlink()
+ {
+ SYMTARGET="$(v=`ls -l "$2" 2>/dev/null` ; echo ${v##*> })"
+ if [ -n "$SYMTARGET" ] ; then
+ echo "$SYMTARGET"
+ return 0
+ else
+ return 1
+ fi
+ }
+fi
+
+## /etc/yaboot.conf with password should not be world readable.
+permcheck()
+{
+if [ -L "$bootconf" ] ; then
+ local realfile="$(readlink -f "$bootconf")" || return 0
+else
+ local realfile="$bootconf"
+fi
+
+## don't bother if we could not read the symlink
+[ -z "$realfile" ] && return 0
+[ ! -f "$realfile" ] && return 0
+
+## get permissions, and don't bother checking if we can't
+local PERM=`v=$(ls -l "$realfile" 2>/dev/null) ; echo ${v%% *}`
+[ -z "$PERM" ] && return 0
+[ `echo ${#PERM}` != 10 ] && return 0
+
+case "$PERM" in
+ -rw-------|-r--------)
+ if [ ! -O "$realfile" -a `id -u` = 0 ] ; then
+ echo 1>&2 "$PRG: Warning: $bootconf is not owned by root"
+ fi
+ ;;
+ -rw-r-----|-r--r-----)
+ if [ ! -O "$realfile" -a `id -u` = 0 ] ; then
+ echo 1>&2 "$PRG: Warning: $bootconf is not owned by root"
+ fi
+ if [ ! -G "$realfile" -a `id -g` = 0 ] ; then
+ echo 1>&2 "$PRG: Warning: $bootconf is not owned by group root"
+ fi
+ ;;
+ -r--r--r--|-rw-r--r--|-rw-rw-r--|-rw-rw-rw-|-rw-rw----)
+ echo 1>&2 "$PRG: Warning: Insecure permissions on $bootconf: $PERM should be -rw-------"
+ ;;
+ *)
+ echo 1>&2 "$PRG: Warning: Incorrect permissions on $bootconf: $PERM should be -rw-------"
+ ;;
+esac
+}
+
+convertpath()
+{
+ ## figure out bootstrap device OF pathname if user did not supply it.
+ if [ -z "$ofboot" ] ; then
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Finding OpenFirmware device path to \`$boot'..."
+ ofboot="$(ofpath $boot)"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Unable to find OpenFirmware path for boot=$boot"
+ echo 1>&2 "$PRG: Please add ofboot=<path> where <path> is the OpenFirmware path to $boot to $CONF"
+ local CONVERR=1
+ fi
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: ofboot set to \`$ofboot'"
+ fi
+
+ ## figure out OF device path for macos/macosx if user supplied a unix device node.
+ if [ -n "$bsd" ] ; then
+ case "$bsd" in
+ /dev/*)
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Finding OpenFirmware device path to \`$bsd'..."
+ local sbsd="$bsd"
+ bsd="$(ofpath $bsd)"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Unable to determine OpenFirmware path for bsd=$sbsd"
+ echo 1>&2 "$PRG: Try specifying the real OpenFirmware path for bsd=$sbsd in $CONF"
+ local CONVERR=1
+ fi
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: bsd set to \`$bsd' from \`$sbsd'"
+ ;;
+ *)
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: bsd left alone: \`$bsd'"
+ ;;
+ esac
+ fi
+
+ if [ -n "$macos" ] ; then
+ case "$macos" in
+ /dev/*)
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Finding OpenFirmware device path to \`$macos'..."
+ local smacos="$macos"
+ macos="$(ofpath $macos)"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Unable to determine OpenFirmware path for macos=$smacos"
+ echo 1>&2 "$PRG: Try specifying the real OpenFirmware path for macos=$smacos in $CONF"
+ local CONVERR=1
+ fi
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: macos set to \`$macos' from \`$smacos'"
+ ;;
+ *)
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: macos left alone: \`$macos'"
+ ;;
+ esac
+ fi
+
+ if [ -n "$macosx" ] ; then
+ case "$macosx" in
+ /dev/*)
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Finding OpenFirmware device path to \`$macosx'..."
+ local smacosx="$macosx"
+ macosx="$(ofpath $macosx)"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Unable to determine OpenFirmware path for macosx=$smacosx"
+ echo 1>&2 "$PRG: Try specifying the real OpenFirmware path for macosx=$smacosx in $CONF"
+ local CONVERR=1
+ fi
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: macosx set to \`$macosx' from \`$smacosx'"
+ ;;
+ *)
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: macosx left alone: \`$macosx'"
+ ;;
+ esac
+ fi
+
+ if [ -n "$darwin" ] ; then
+ case "$darwin" in
+ /dev/*)
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Finding OpenFirmware device path to \`$darwin'..."
+ local sdarwin="$darwin"
+ darwin="$(ofpath $darwin)"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Unable to determine OpenFirmware path for darwin=$sdarwin"
+ echo 1>&2 "$PRG: Try specifying the real OpenFirmware path for darwin=$sdarwin in $CONF"
+ local CONVERR=1
+ fi
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: darwin set to \`$darwin' from \`$sdarwin'"
+ ;;
+ *)
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: darwin left alone: \`$darwin'"
+ ;;
+ esac
+ fi
+
+ if [ "$CONVERR" = 1 ] ; then
+ return 1
+ else
+ return 0
+ fi
+}
+
+## make sure the hfsutils we need are installed and executable.
+checkhfsutils()
+{
+ if (command -v hmount > /dev/null 2>&1) ; then
+ [ -x `command -v hmount` ] || FAIL=1 ; else FAIL=1 ; fi
+ if (command -v humount > /dev/null 2>&1) ; then
+ [ -x `command -v humount` ] || FAIL=1 ; else FAIL=1 ; fi
+ if (command -v hcopy > /dev/null 2>&1) ; then
+ [ -x `command -v hcopy` ] || FAIL=1 ; else FAIL=1 ; fi
+ if (command -v hattrib > /dev/null 2>&1) ; then
+ [ -x `command -v hattrib` ] || FAIL=1 ; else FAIL=1 ; fi
+ if (command -v hformat > /dev/null 2>&1) ; then
+ [ -x `command -v hformat` ] || FAIL=1 ; else FAIL=1 ; fi
+
+ if [ "$FAIL" = 1 ] ; then
+ return 1
+ else
+ return 0
+ fi
+}
+
+## This is gross, IBM CHRP OF needs a .note added to the yaboot
+## binary, nobody knows whether this note will affect PowerMac OF or
+## not (or could in the future).
+hack_yaboot()
+{
+ local YBDIR="${install%/*}"
+ if [ -x "$YBDIR/addnote" ] ; then
+ TMPYABOOT=`mktemp -q "$TMP/yaboot.XXXXXX"`
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Could not create temporary file, aborting."
+ return 1
+ else
+ if (cat "$install" > "$TMPYABOOT" 2> /dev/null) ; then
+ install="$TMPYABOOT"
+ else
+ echo 1>&2 "$PRG: Could not create temporary file, aborting."
+ return 1
+ fi
+ fi
+ [ "$DEBUG" = 1 ] && echo "$PRG: Embedding CHRP note section in temp yaboot..."
+ "$YBDIR/addnote" "$install" > /dev/null 2>&1
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Could not install note section required by your architecture"
+ return 1
+ fi
+ else
+ echo 1>&2 "$PRG: Your architecture requires $YBDIR/addnote which cannot be found"
+ return 1
+ fi
+ return 0
+}
+
+## install using userspace utilities rather then kernel filesytem
+## support. hfsutils only, mtools not supported.
+util_install()
+{
+ ## catch signals, and humount, cleanup done by trap 0.
+ trap "humount $boot ; exit 129" 1
+ trap "echo 1>&2 $SIGINT ; humount $boot ; exit 130" 2
+ trap "humount $boot ; exit 131" 3
+ trap "humount $boot ; exit 143" 15
+
+ ## filenames on bootstrap partition. ofboot hard codes yaboot.
+ local BTFILE=yaboot
+ local CFFILE=yaboot.conf
+
+ ## if there is a magicboot script to install we will give it the
+ ## hfstype (should be "tbxi") and give yaboot type "boot".
+ if [ "$magicboot" ] ; then
+ local BTTYPE=boot
+ else
+ local BTTYPE="$hfstype"
+ fi
+
+ if [ -n "$magicboot" ] ; then
+ local WRAP="${magicboot##*/}"
+ fi
+
+ ## set verbose messages here so they don't show temporary file paths
+ local INSTALLFIRST="$PRG: Installing first stage bootstrap $magicboot onto $boot..."
+ local INSTALLPRIMARY="$PRG: Installing primary bootstrap $install onto $boot..."
+
+ ## repoint magicboot as the real first stage loader if using the
+ ## modern automatic generating ofboot.b.
+ if [ -n "$FIRST" ] ; then
+ magicboot="$FIRST"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: set magicboot to $FIRST"
+ fi
+
+ ## gross hack, add note section for IBM CHRP
+ if [ "$ADDNOTE" = yes ] ; then
+ hack_yaboot || return 1
+ fi
+
+ if [ "$fstype" = hfs ] ; then
+ if [ "$protect" = yes ] ; then
+ local LOCK="+l"
+ fi
+
+ if [ "$hide" = yes ] ; then
+ local INVISIBLE="+i"
+ fi
+
+ ## make sure the device is not mounted as a filesystem before
+ ## we start mucking with it directly.
+ mount | grep "^$boot\>" > /dev/null
+ if [ $? = 0 ] ; then
+ echo 1>&2 "$PRG: $boot appears to be mounted! aborting."
+ return 1
+ fi
+
+ ## 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
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: $boot appears to have never had a bootstrap installed, please run mkofboot"
+ return 1
+ fi
+
+ ## must be explicit with target filename to avoid hfsutils
+ ## braindamage ("_" -> " " filename mangling) also avoid
+ ## ambiguity in the bootstrap partition.
+ if [ -n "$magicboot" ] ; then
+ [ "$VERBOSE" = 1 ] && echo "$INSTALLFIRST"
+ hcopy -r "$magicboot" :ofboot.b
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: An error occured while writing to $boot"
+ return 1
+ fi
+ fi
+
+ [ "$VERBOSE" = 1 ] && echo "$INSTALLPRIMARY"
+ hcopy -r "$install" :"$BTFILE"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: An error occured while writing to $boot"
+ return 1
+ fi
+
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Installing $bootconf to $boot..."
+ hcopy -r "$bootconf" :"$CFFILE"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: An error occured while writing to $boot"
+ return 1
+ fi
+
+ ## set all file's attributes, if a magicboot script exists it
+ ## gets the configured hfstype instead of yaboot (should be
+ ## "tbxi") so it gets booted by OF.
+ if [ "$magicboot" ] ; then
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Setting attributes on $WRAP..."
+ hattrib -t "$hfstype" -c "$hfscreator" $INVISIBLE $LOCK :ofboot.b
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Warning: error setting attributes on $WRAP"
+ echo 1>&2 "$PRG: This is probably bad but we'll ignore it."
+ fi
+ fi
+
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Setting attributes on $BTFILE..."
+ hattrib -t "$BTTYPE" -c "$hfscreator" $INVISIBLE $LOCK :"$BTFILE"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Warning: error setting attributes on $BTFILE"
+ echo 1>&2 "$PRG: This is probably bad but we'll ignore it"
+ fi
+
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Setting attributes on $CFFILE..."
+ hattrib -t "conf" -c "$hfscreator" $INVISIBLE $LOCK :"$CFFILE"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Warning: error setting attributes on $CFFILE"
+ echo 1>&2 "$PRG: This is probably unimportant so we'll ignore it"
+ fi
+
+ ## bless the root directory so OF will find the boot file
+ if [ "$bless" = yes ] ; then
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Blessing $boot with Holy Penguin Pee..."
+ hattrib -b :
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Warning: error blessing $boot"
+ echo 1>&2 "$PRG: This is probably bad but we'll ignore it"
+ fi
+ fi
+
+ ## clean up the ~/.hcwd file hmount creates
+ humount "$boot" > /dev/null
+ sync ; sync
+
+ ## use explicit filename if we don't bless.
+ if [ "$bless" = yes ] ; then
+ local OFFILE='\\:tbxi'
+ else
+ if [ -n "$magicboot" ] ; then
+ local OFFILE=ofboot.b
+ else
+ local OFFILE="$BTFILE"
+ fi
+ fi
+
+ ## update the boot-device variable in OF nvram.
+ if [ "$nonvram" = 0 ] ; then
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Updating OpenFirmware boot-device variable in nvram..."
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: boot-device=${ofboot},${OFFILE}"
+ nvsetenv boot-device "${ofboot},${OFFILE}"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: An error occured while updating nvram, we'll ignore it"
+ fi
+ fi
+
+ else
+ echo 1>&2 "$PRG: mtools support is not implemented"
+ echo 1>&2 "$PRG: Use --mount or add \`usemount' to $CONF"
+ return 1
+ fi
+
+ return 0
+}
+
+## used by mnt_install so mntpoint= can be supported in a cleaner way.
+mnt()
+{
+ ## we can even create bootstrap filesystem images directly if you
+ ## ever wanted too.
+ if [ -f "$boot" ] ; then
+ local loop=",loop"
+ fi
+
+ if [ -e "$TMP/bootstrap.$$" ] ; then
+ echo 1>&2 "$PRG: $TMP/bootstrap.$$ exists, aborting."
+ return 1
+ fi
+
+ mkdir -m 700 "$TMP/bootstrap.$$"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Could not create mountpoint directory, aborting."
+ return 1
+ fi
+
+ mount | grep "^$boot\>" > /dev/null
+ if [ $? = 0 ] ; then
+ echo 1>&2 "$PRG: $boot appears to be mounted! aborting."
+ return 1
+ fi
+
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Mounting $boot..."
+ mount -t "$fstype" -o rw,umask=077$loop "$boot" "$TMP/bootstrap.$$"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: An error occured mounting $boot"
+ return 1
+ fi
+
+ ## catch signals, set here to avoid umounting something we did not
+ ## mount. cleanup done by trap 0.
+ trap "umount $boot ; exit 129" 1
+ trap "echo 1>&2 $SIGINT ; umount $boot ; exit 130" 2
+ trap "umount $boot ; exit 131" 3
+ trap "umount $boot ; exit 143" 15
+
+ TARGET="$TMP/bootstrap.$$"
+ return 0
+}
+
+## umnt funtion which checks whether we mounted anything or not, for
+## mntpoint= this makes the code below cleaner IMO.
+umnt()
+{
+ if [ -z "$mntpoint" ] ; then
+ [ "$1" = failure ] && echo 1>&2 "$PRG: Attempting to umount $boot..."
+ umount "$2"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: umount of $boot failed!"
+ return 1
+ else
+ [ "$1" = failure ] && echo 1>&2 "$PRG: umount successfull"
+ return 0
+ fi
+ else
+ return 0
+ fi
+}
+
+## Use kernel filesytem drivers to mount the bootstrap partition like
+## any other filesystem and copy the files there with standard un*x
+## utilities.
+mnt_install()
+{
+ local BTFILE=yaboot
+
+ ## msdosfs is broken, yaboot may not support this filename.
+ if [ "$fstype" = msdos ] ; then
+ local CFFILE=yaboot.cnf
+ else
+ local CFFILE=yaboot.conf
+ fi
+
+ if [ "$magicboot" ] ; then
+ local WRAP="${magicboot##*/}"
+ fi
+
+ ## set verbose messages here so they don't show temporary file paths
+ local INSTALLFIRST="$PRG: Installing first stage bootstrap $magicboot onto $boot..."
+ local INSTALLPRIMARY="$PRG: Installing primary bootstrap $install onto $boot..."
+
+ ## repoint magicboot as the real first stage loader if using the
+ ## modern automatic generating ofboot.b.
+ if [ "$FIRST" ] ; then
+ magicboot="$FIRST"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: set magicboot to $FIRST"
+ fi
+
+ ## gross hack, add note section for IBM CHRP
+ if [ "$ADDNOTE" = yes ] ; then
+ hack_yaboot || return 1
+ fi
+
+ ## call mnt() function to take care of mounting filesystem if needed
+ if [ -z "$mntpoint" ] ; then
+ mnt || return 1
+ else
+ TARGET="$mntpoint"
+ fi
+
+ ## this is probably insecure on modern filesystems, but i think
+ ## safe on crippled hfs/dosfs. user should ensure mntpoint= is safe.
+ if [ -n "$magicboot" ] ; then
+ [ "$VERBOSE" = 1 ] && echo "$INSTALLFIRST"
+ cp -f "$magicboot" "$TARGET/ofboot.b"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: An error occured while writing to $boot"
+ umnt failure "$TARGET"
+ return 1
+ fi
+ fi
+
+ [ "$VERBOSE" = 1 ] && echo "$INSTALLFIRST"
+ cp -f "$install" "$TARGET/$BTFILE"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: An error occured while writing to $boot"
+ umnt failure "$TARGET"
+ return 1
+ fi
+
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Installing $bootconf on $boot..."
+ cp -f "$bootconf" "$TARGET/$CFFILE"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: An error occured while writing to $boot"
+ umnt failure "$TARGET"
+ return 1
+ fi
+
+ if [ "$protect" = yes ] ; then
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Setting read-only attributes..."
+ chmod a-w "$TARGET/$BTFILE"
+ chmod a-w "$TARGET/$CFFILE"
+ if [ "$magicboot" ] ; then
+ chmod a-w "$TARGET/ofboot.b"
+ fi
+ fi
+
+ sync ; sync
+ umnt success "$TARGET" || return 1
+
+ ## make variable with a \ to avoid shell fsckage. ugly ugly ugly.
+ local BS='\'
+ if [ -n "$magicboot" ] ; then
+ [ -n "$OFDIR" ] && OFDIR="${BS}${OFDIR}${BS}"
+ local OFFILE="${OFDIR}ofboot.b"
+ else
+ [ -n "$OFDIR" ] && OFDIR="${BS}${OFDIR}${BS}"
+ local OFFILE="${OFDIR}${BTFILE}"
+ fi
+
+ ## update the boot-device variable in OF nvram.
+ if [ "$nonvram" = 0 ] ; then
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Updating OpenFirmware boot-device variable in nvram..."
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: boot-device=${ofboot},${OFFILE}"
+ nvsetenv boot-device "${ofboot},${OFFILE}"
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: An error occured while updating nvram, we'll ignore it"
+ fi
+ else
+ echo 1>&2 "$PRG: Warning: You must manually configure OpenFirmware to boot."
+ fi
+
+ return 0
+}
+
+## raw installation, for IBM RS/6000 hardware, yaboot is dded to the
+## bootstrap partition.
+raw_install()
+{
+ ## make sure the device is not mounted as a filesystem before
+ ## we start mucking with it directly.
+ mount | grep "^$boot\>" > /dev/null
+ if [ $? = 0 ] ; then
+ echo 1>&2 "$PRG: $boot appears to be mounted! aborting."
+ return 1
+ fi
+
+ ## set verbosity message before munging the yaboot pathname
+ local INSTALLPRIMARY="$PRG: Installing primary bootstrap $install onto $boot..."
+
+ ## gross hack, add note section for IBM CHRP
+ if [ "$ADDNOTE" = yes ] ; then
+ hack_yaboot || return 1
+ fi
+
+ [ "$VERBOSE" = 1 ] && echo "$INSTALLPRIMARY"
+ dd if=/dev/zero of="$boot" bs=512 count=1600 > /dev/null 2>&1
+ dd if="$install" of="$boot" bs=512 > /dev/null 2>&1
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Installation failed."
+ return 1
+ fi
+ sync ; sync
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Installation successful"
+}
+
+## make sure the first stage ofboot generator is compatible.
+checkfirststage()
+{
+ grep -q "^#%ybinscript-" "$magicboot" 2> /dev/null
+ if [ "$?" = 0 ] ; then
+ local magic=`grep "^#%ybinscript-" "$magicboot"`
+ local ver="${magic##*-}"
+ if [ "$ver" = "1.1" ] ; then
+ FIRSTSTG=compat
+ return 0
+ else
+ echo 1>&2 "$PRG: Incompatible version of first stage loader $magicboot. aborting..."
+ return 1
+ fi
+ else
+ FIRSTSTG=old
+ return 0
+ fi
+}
+
+## build the first stage loader.
+mkfirststage()
+{
+ ## must have 7 backslashes to == \\ printf + shell = bizarre... or,
+ ## make special variable to contain a \ (need \\ to make \) to work
+ ## around echo -e -n brokeness.
+ local BS='\\'
+ local OS=1
+
+ ## deal with mntpoint=
+ [ -n "$OFDIR" ] && local OFDIR="${BS}${OFDIR}${BS}"
+
+ ## some misguided people insist on installing OSX on
+ ## HorribleFileSystem+ instead of UFS, as a result MacOS deblesses
+ ## OSX, making it unbootable. if apple localizes the filesystem hierarchy again screw it.
+ [ "$brokenosx" = yes ] && local OSXBOOT="${BS}System${BS}Library${BS}CoreServices${BS}BootX"
+ [ "$brokenosx" = no ] && local OSXBOOT="${BS}${BS}:tbxi"
+
+ ## assign variables for configured menu options.
+ [ "$usemount" = no -a "$bless" = yes ] && local YB="yaboot GNU l $ofboot ,${BS}${BS}yaboot"
+ [ "$usemount" = yes -o "$bless" = no ] && local YB="yaboot GNU l $ofboot ,${OFDIR}yaboot"
+ [ -n "$bsd" ] && OS="$(($OS + 1))" && local BSD="bsd BSD b $bsd ,${BS}ofwboot.elf"
+ [ -n "$macos" ] && OS="$(($OS + 1))" && local MAC="macos MacOS m $macos ,${BS}${BS}:tbxi"
+ [ -n "$macosx" ] && OS="$(($OS + 1))" && local MX="macosx MacOSX x $macosx ,${OSXBOOT}"
+ [ -n "$darwin" ] && OS="$(($OS + 1))" && local DW="darwin Darwin d $darwin ,${BS}${BS}:tbxi"
+ [ "$cdrom" = yes ] && OS="$(($OS + 1))" && local CD="cd CDROM c cd: ,${BS}${BS}:tbxi"
+ [ "$network" = yes ] && OS="$(($OS + 1))" && local NET="net Network n enet: 0"
+ [ "$of" = yes ] && OS="$(($OS + 1))" && local OF="of OpenFirmware o quit now"
+ [ "$DEBUG" = 1 ] && echo 1>&2 "$PRG: DEBUG: OS=$OS"
+
+ ## call ofboot,
+ ## Usage: OS-count defaultos timeout fgc bgc osname oslabel oskey osdev osfile ...
+ [ "$DEBUG" = 1 ] && $PRINTF 1>&2 "$PRG: DEBUG: /bin/sh $magicboot $OS $defaultos $delay $fbc $bgc $YB $BSD $MAC $MX $DW $CD $NET $OF\n"
+ FIRST="$(/bin/sh "$magicboot" "$OS" "$defaultos" "$delay" $fgc $bgc ${YB} ${BSD} ${MAC} ${MX} ${DW} ${CD} ${NET} ${OF})" || return 1
+
+ return 0
+}
+
+## mkofboot function.
+mkoffs()
+{
+ mount | grep "^$boot\>" > /dev/null
+ if [ $? = 0 ] ; then
+ echo 1>&2 "$PRG: $boot appears to be mounted! aborting."
+ return 1
+ fi
+
+ case "$fstype" in
+ hfs)
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Creating HFS 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
+ hformat -l bootstrap "$boot" > /dev/null
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: HFS filesystem creation failed!"
+ return 1
+ fi
+ humount "$boot" ## otherwise we might get confused.
+ return 0
+ ;;
+ msdos)
+ if (command -v mkdosfs > /dev/null 2>&1) ; then
+ [ -x `command -v mkdosfs` ] || FAIL=1 ; else FAIL=1 ; fi
+ if [ "$FAIL" = 1 ] ; then
+ echo 1>&2 "$PRG: mkdosfs is not installed or cannot be found"
+ return 1
+ fi
+
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Creating DOS 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
+ mkdosfs -n bootstrap "$boot" > /dev/null
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: DOS filesystem creation failed!"
+ return 1
+ fi
+ return 0
+ ;;
+ esac
+}
+
+confirm()
+{
+ if [ "$FORCE" = yes ] ; then
+ return 0
+ else
+ echo 1>&2
+ [ "$fstype" = raw ] && $PRINTF 1>&2 "$PRG: Overwrite contents of $boot with $install? [y/N] "
+ [ "$fstype" != raw ] && $PRINTF 1>&2 "$PRG: Create $fstype filesystem on $boot? [y/N] "
+ read ans
+ case "$ans" in
+ y|Y)
+ return 0
+ ;;
+ *)
+ echo 1>&2 "$PRG: Abort."
+ return 2
+ ;;
+ esac
+ fi
+}
+
+## for fstype=raw check if an ELF binary has already been dded.
+luserck()
+{
+ if [ "$(dd if="$boot" bs=1 skip=1 count=3 2>/dev/null)" = ELF ] ; then
+ return 0
+ else
+ echo 1>&2 "$PRG: This partition has never had yaboot installed before, please run mkofboot"
+ return 1
+ fi
+}
+
+mkconf()
+{
+## defaults for this are defined at the beginning of the script with
+## other variables.
+
+echo \
+"## yaboot configuration file generated by ybin $VERSION
+
+device=$device
+timeout=$timeout
+
+image=$image
+ label=$label
+ partition=$partition
+ root=$root
+ read-only
+" > "$TMPCONF" || return 1
+
+[ "$DEBUG" = 1 ] && $PRINTF 1>&2 "\nDEBUG: autoconf:\n----\n" && cat "$TMPCONF" 1>&2 && echo 1>&2 "----"
+return 0
+}
+
+## take out the trash.
+cleanup()
+{
+ if [ -n "$TMPCONF" ] ; then rm -f "$TMPCONF" ; fi
+ if [ -n "$FIRST" ] ; then rm -f "$FIRST" ; fi
+ if [ -n "$TMPYABOOT" ] ; then rm -f "$TMPYABOOT" ; fi
+ if [ -d "$TMP/bootstrap.$$" -a "$usemount" = yes ] ; then rmdir "$TMP/bootstrap.$$" ; fi
+ return 0
+}
+
+##########
+## Main ##
+##########
+
+## absurdly bloated case statement to parse command line options.
+if [ $# != 0 ] ; then
+ while true ; do
+ case "$1" in
+ -V|--version)
+ version
+ exit 0
+ ;;
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ --debug)
+ DEBUG=1
+ shift
+ ;;
+ -v|--verbose)
+ VERBOSE=1
+ shift
+ ;;
+ -f|--force)
+ FORCE=yes
+ shift
+ ;;
+ -b|--boot)
+ if [ -n "$2" ] ; then
+ boot="$2"
+ ARGBT=1
+ shift 2
+ else
+ echo 1>&2 "$PRG: option requires an argument $1"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ fi
+ ;;
+ -o|--ofboot)
+ if [ -n "$2" ] ; then
+ ofboot="$2"
+ ARGOB=1
+ shift 2
+ else
+ echo 1>&2 "$PRG: option requires an argument $1"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ fi
+ ;;
+ -i|--install)
+ if [ -n "$2" ] ; then
+ install="$2"
+ ARGBF=1
+ shift 2
+ else
+ echo 1>&2 "$PRG: option requires an argument $1"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ fi
+ ;;
+ -C|--config)
+ if [ -n "$2" ] ; then
+ CONF="$2"
+ bootconf="$2"
+ ERR=" Error in $CONF:"
+ shift 2
+ else
+ echo 1>&2 "$PRG: option requires an argument $1"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ fi
+ ;;
+ -m|--magicboot)
+ if [ -n "$2" ] ; then
+ magicboot="$2"
+ ARGWP=1
+ shift 2
+ else
+ echo 1>&2 "$PRG: option requires an argument $1"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ fi
+ ;;
+ --filesystem)
+ if [ -n "$2" ] ; then
+ fstype="$2"
+ ARGFS=1
+ shift 2
+ else
+ echo 1>&2 "$PRG: option requires an argument $1"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ fi
+ ;;
+ --nobless)
+ bless=no
+ ARGBS=1
+ shift
+ ;;
+ -M|--mount)
+ usemount=yes
+ ARGMT=1
+ shift
+ ;;
+ --protect)
+ protect=yes
+ ARGPT=1
+ shift
+ ;;
+ --hide)
+ hide=yes
+ ARGHD=1
+ shift
+ ;;
+ --nonvram)
+ nonvram=1
+ ARGNV=1
+ shift
+ ;;
+ --device)
+ if [ -n "$2" ] ; then
+ device="$2"
+ bootconf=auto
+ shift 2
+ else
+ echo 1>&2 "$PRG: option requires an argument $1"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ fi
+ ;;
+ --timeout)
+ if [ -n "$2" ] ; then
+ timeout="$2"
+ bootconf=auto
+ shift 2
+ else
+ echo 1>&2 "$PRG: option requires an argument $1"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ fi
+ ;;
+ --image)
+ if [ -n "$2" ] ; then
+ image="$2"
+ bootconf=auto
+ 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"
+ bootconf=auto
+ shift 2
+ else
+ echo 1>&2 "$PRG: option requires an argument $1"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ fi
+ ;;
+ --partition)
+ if [ -n "$2" ] ; then
+ partition="$2"
+ bootconf=auto
+ shift 2
+ else
+ echo 1>&2 "$PRG: option requires an argument $1"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ fi
+ ;;
+ --root)
+ if [ -n "$2" ] ; then
+ root="$2"
+ bootconf=auto
+ 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
+ ;;
+ *)
+ echo 1>&2 "$PRG: unrecognized option \`$1'"
+ echo 1>&2 "Try \`$PRG --help' for more information."
+ exit 1
+ ;;
+ esac
+ done
+fi
+
+## check that specified config file exists, unless its /dev/null in
+## which case we assume all options are done on the command line.
+if [ "$CONF" = /dev/null ] ; then
+ true
+else
+ confexist || exit 1
+fi
+
+## if there is no config file use the automatic generation to make a
+## generic yaboot.conf. do this before the confcheck to avoid wierd errors.
+if [ "$bootconf" = /dev/null ] ; then
+ if (command -v yabootconfig > /dev/null 2>&1) ; then
+ echo 1>&2 "$PRG: Warning: no /etc/yaboot.conf, running yabootconfig to make one"
+ yabootconfig --noinstall --quiet
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: yabootconfig failed, please supply a valid /etc/yaboot.conf"
+ echo 1>&2 "$PRG: You may also use $PRG's --boot, --image, --partition, and --device switches"
+ echo 1>&2 "$PRG: These switches will cause $PRG to generate a basic yaboot.conf on the fly"
+ exit 1
+ else
+ CONF=/etc/yaboot.conf
+ bootconf=$CONF
+ ERR=" Error in $CONF:"
+ confexist || exit 1
+ fi
+ fi
+fi
+
+## Checks if each option was defined on the command line, and if so
+## don't read it from the configuration file. this avoids
+## configuration options from being set null, as well as command line
+## options from being clobbered.
+[ "$ARGBT" != 1 -a $(parseconf ck boot) = 0 ] && boot=`parseconf str boot`
+[ "$ARGOB" != 1 -a $(parseconf ck ofboot) = 0 ] && ofboot=`parseconf str ofboot`
+[ "$ARGBF" != 1 -a $(parseconf ck install) = 0 ] && install=`parseconf str install`
+[ "$ARGWP" != 1 -a $(parseconf ck magicboot) = 0 ] && magicboot=`parseconf str magicboot`
+[ "$ARGMT" != 1 -a $(parseconf flag usemount) = 0 ] && usemount=yes
+[ "$ARGFS" != 1 -a $(parseconf ck fstype) = 0 ] && fstype=`parseconf str fstype`
+[ "$ARGBS" != 1 -a $(parseconf flag nobless) = 0 ] && bless=no
+[ "$ARGPT" != 1 -a $(parseconf flag protect) = 0 ] && protect=yes
+[ "$ARGHD" != 1 -a $(parseconf flag hide) = 0 ] && hide=yes
+[ "$ARGNV" != 1 -a $(parseconf flag nonvram) = 0 ] && nonvram=1
+[ $(parseconf ck hfstype) = 0 ] && hfstype=`parseconf str hfstype`
+[ $(parseconf ck hfscreator) = 0 ] && hfscreator=`parseconf str hfscreator`
+[ $(parseconf ck mntpoint) = 0 ] && mntpoint=`parseconf str mntpoint`
+[ $(parseconf ck delay) = 0 ] && delay=`parseconf str delay`
+[ $(parseconf ck timeout) = 0 ] && timeout=`parseconf str timeout`
+[ $(parseconf ck bsd) = 0 ] && bsd=`parseconf str bsd`
+[ $(parseconf ck macos) = 0 ] && macos=`parseconf str macos`
+[ $(parseconf ck macosx) = 0 ] && macosx=`parseconf str macosx`
+[ $(parseconf ck darwin) = 0 ] && darwin=`parseconf str darwin`
+[ $(parseconf ck defaultos) = 0 ] && defaultos=`parseconf str defaultos`
+[ $(parseconf ck fgcolor) = 0 ] && fgcolor=`parseconf str fgcolor`
+[ $(parseconf ck bgcolor) = 0 ] && bgcolor=`parseconf str bgcolor`
+[ $(parseconf ck icon) = 0 ] && export YBINOFICON=`parseconf str icon`
+[ $(parseconf flag enablecdboot) = 0 ] && cdrom=yes
+[ $(parseconf flag enablenetboot) = 0 ] && network=yes
+[ $(parseconf flag enableofboot) = 0 ] && of=yes
+[ $(parseconf flag brokenosx) = 0 ] && brokenosx=yes
+
+## ffs!! rtfm! foad!
+if [ "$boot" = unconfigured ] ; then
+ echo 1>&2 "$PRG: You must specify the device for the bootstrap partition. (ie: boot=/dev/hdaX)"
+ echo 1>&2 "$PRG: Try \`$PRG --help' for more information."
+ exit 1
+fi
+
+## if there is still no config file use the automatic generation to make a
+## generic yaboot.conf. do this before the confcheck to avoid wierd errors.
+if [ "$bootconf" = /dev/null ] ; then
+ echo 1>&2 "$PRG: Warning: no yaboot.conf, using generic configuration."
+ bootconf=auto
+fi
+
+## mntpoint is incompatible with mkofboot.
+if [ "$PRG" = mkofboot -a -n "$mntpoint" ] ; then
+ echo 1>&2 "$PRG: Cannot be used with \`mntpoint='"
+ exit 1
+fi
+
+## validate configuration for sanity.
+checkconf || exit 1
+
+## check that we can use ofpath, its only needed for magicboot script
+## building and nvram updates.
+if [ -n "$magicboot" -o "$nonvram" = 0 ] ; then
+ if [ -z "$ofboot" -o -n "$macos" -o -n "$macosx" -o -n "$darwin" ] ; then
+ if (command -v ofpath > /dev/null 2>&1) ; then
+ [ -x `command -v ofpath` ]
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: ofpath could not be found, aborting."
+ exit 1
+ fi
+ else
+ echo 1>&2 "$PRG: ofpath could not be found, aborting."
+ exit 1
+ fi
+ fi
+fi
+
+## if password is set in yaboot.conf make sure permissions on that
+## file are safe, warn if not.
+if (grep -q '^[[:space:]]*password[[:space:]]*=' "$bootconf" > /dev/null 2>&1) ; then
+ permcheck
+fi
+
+## check if we are root if needed.
+if [ "$usemount" = yes -a -z "$mntpoint" ] ; then
+ if [ `id -u` != 0 ] ; then
+ echo 1>&2 "$PRG: \`usemount' requires root privileges, go away."
+ exit 1
+ fi
+fi
+
+if [ "$fstype" = hfs ] ; then
+ checkhfsutils
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: hfsutils is not installed or cannot be found"
+ echo 1>&2 "$PRG: Try --mount if `uname -sr` supports HFS"
+ exit 1
+ fi
+fi
+
+## convert unix device nodes to OpenFirmware pathnames
+if [ -n "$magicboot" -o "$nonvram" = 0 ] ; then
+ convertpath || exit 1
+fi
+
+## yaboot.conf autogeneration. MUST have secure mktemp to
+## avoid race conditions. Debian's mktemp qualifies.
+if [ "$bootconf" = auto ] ; then
+ TMPCONF=`mktemp -q "$TMP/$PRG.XXXXXX"`
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: Could not create temporary file, aborting."
+ exit 1
+ fi
+
+ mkconf
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: An error occured generating yaboot.conf, aborting."
+ exit 1
+ fi
+
+ bootconf="$TMPCONF"
+fi
+
+if [ -n "$magicboot" ] ; then
+ checkfirststage || exit 1
+ if [ "$FIRSTSTG" = compat ] ; then
+ mkfirststage
+ if [ $? != 0 ] ; then
+ echo 1>&2 "$PRG: An error occured while building first stage loader. aborting..."
+ exit 1
+ fi
+ fi
+fi
+
+case "$PRG" in
+ ybin)
+ case "$usemount" in
+ no)
+ if [ "$fstype" = raw ] ; then
+ luserck || exit 1
+ raw_install || exit 1
+ else
+ util_install || exit 1
+ fi
+ exit 0
+ ;;
+ yes)
+ mnt_install || exit 1
+ exit 0
+ ;;
+ esac
+ ;;
+ mkofboot)
+ case "$usemount" in
+ no)
+ ## its not nice to erase the partition and then bail!
+ if [ "$fstype" = msdos ] ; then
+ echo 1>&2 "$PRG: mtools support is not implemented"
+ echo 1>&2 "$PRG: Use --mount or add \`usemount' to $CONF"
+ exit 1
+ fi
+ confirm || exit 2
+ if [ "$fstype" = raw ] ; then
+ raw_install || exit 1
+ else
+ mkoffs || exit 1
+ util_install || exit 1
+ fi
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Installation complete."
+ exit 0
+ ;;
+ yes)
+ confirm || exit 2
+ mkoffs || exit 1
+ mnt_install || exit 1
+ [ "$VERBOSE" = 1 ] && echo "$PRG: Installation complete."
+ exit 0
+ ;;
+ esac
+ ;;
+esac
+
+exit 0