]> git.ozlabs.org Git - yaboot.git/commitdiff
Commit yaboot 1.3.0
authorEthan Benson <erbenson@alaska.net>
Mon, 25 Mar 2002 07:43:37 +0000 (07:43 +0000)
committerEthan Benson <erbenson@alaska.net>
Mon, 25 Mar 2002 07:43:37 +0000 (07:43 +0000)
Commit yaboot 1.3.0.
git-archimport-id: erbenson@alaska.net--public/yaboot--devel--1.3--patch-1

101 files changed:
BUGS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog
INSTALL [new file with mode: 0644]
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
README.man.patch [new file with mode: 0644]
THANKS [new file with mode: 0644]
TODO [new file with mode: 0644]
changelog [new file with mode: 0644]
doc/README.ofboot [new file with mode: 0644]
doc/README.ofpath [new file with mode: 0644]
doc/README.rs6000 [new file with mode: 0644]
doc/examples/README.dualboot.chrp [new file with mode: 0644]
doc/examples/README.mbicons [new file with mode: 0644]
doc/examples/README.simpleboot.chrp [new file with mode: 0644]
doc/examples/dualboot.chrp [new file with mode: 0644]
doc/examples/large-penguin.mbicon [new file with mode: 0644]
doc/examples/simpleboot.chrp [new file with mode: 0644]
doc/examples/yaboot.conf.multi-boot [new file with mode: 0644]
doc/examples/yaboot.conf.rs6k [new file with mode: 0644]
etc/yaboot.conf [new file with mode: 0644]
first/ofboot [new file with mode: 0644]
include/asm/elf.h [new file with mode: 0644]
include/asm/ppc_asm.tmpl [new file with mode: 0644]
include/asm/processor.h [new file with mode: 0644]
include/bootinfo.h [new file with mode: 0644]
include/byteorder.h [new file with mode: 0644]
include/cfg.h [new file with mode: 0644]
include/cmdline.h [new file with mode: 0644]
include/ctype.h [new file with mode: 0644]
include/et/com_err.c [new file with mode: 0644]
include/et/com_err.h [new file with mode: 0644]
include/ext2fs/bitops.h [new file with mode: 0644]
include/ext2fs/ext2_err.h [new file with mode: 0644]
include/ext2fs/ext2_io.h [new file with mode: 0644]
include/ext2fs/ext2fs.h [new file with mode: 0644]
include/fdisk-part.h [new file with mode: 0644]
include/file.h [new file with mode: 0644]
include/fs.h [new file with mode: 0644]
include/gui.h [new file with mode: 0644]
include/linux/elf.h [new file with mode: 0644]
include/linux/ext2_fs.h [new file with mode: 0644]
include/linux/iso_fs.h [new file with mode: 0644]
include/linux/stat.h [new file with mode: 0644]
include/linux/types.h [new file with mode: 0644]
include/mac-part.h [new file with mode: 0644]
include/md5.h [new file with mode: 0644]
include/partition.h [new file with mode: 0644]
include/prom.h [new file with mode: 0644]
include/reiserfs/reiserfs.h [new file with mode: 0644]
include/setjm2.h [new file with mode: 0644]
include/setjmp.h [new file with mode: 0644]
include/stdlib.h [new file with mode: 0644]
include/string.h [new file with mode: 0644]
include/swab.h [new file with mode: 0644]
include/types.h [new file with mode: 0644]
include/video.h [new file with mode: 0644]
include/yaboot.h [new file with mode: 0644]
lib/ctype.c [new file with mode: 0644]
lib/libext2fs.a [new file with mode: 0644]
lib/malloc.c [new file with mode: 0644]
lib/nosys.c [new file with mode: 0644]
lib/string.S [new file with mode: 0644]
lib/strstr.c [new file with mode: 0644]
lib/strtol.c [new file with mode: 0644]
lib/vsprintf.c [new file with mode: 0644]
man.patch [new file with mode: 0644]
man/bootstrap.8 [new file with mode: 0644]
man/mkofboot.8 [new file with mode: 0644]
man/ofpath.8 [new file with mode: 0644]
man/yaboot.8 [new file with mode: 0644]
man/yaboot.conf.5 [new file with mode: 0644]
man/yabootconfig.8 [new file with mode: 0644]
man/ybin.8 [new file with mode: 0644]
second/cache.S [new file with mode: 0644]
second/cfg.c [new file with mode: 0644]
second/cmdline.c [new file with mode: 0644]
second/crt0.S [new file with mode: 0644]
second/file.c [new file with mode: 0644]
second/fs.c [new file with mode: 0644]
second/fs_ext2.c [new file with mode: 0644]
second/fs_iso.c [new file with mode: 0644]
second/fs_of.c [new file with mode: 0644]
second/fs_reiserfs.c [new file with mode: 0644]
second/gui/colormap.c [new file with mode: 0644]
second/gui/effects.c [new file with mode: 0644]
second/gui/pcx.c [new file with mode: 0644]
second/gui/video.c [new file with mode: 0644]
second/iso_util.c [new file with mode: 0644]
second/md5.c [new file with mode: 0644]
second/partition.c [new file with mode: 0644]
second/prom.c [new file with mode: 0644]
second/setjmp.S [new file with mode: 0644]
second/yaboot.c [new file with mode: 0644]
util/addnote.c [new file with mode: 0644]
util/elfextract.c [new file with mode: 0644]
ybin/mkofboot [new symlink]
ybin/ofpath [new file with mode: 0755]
ybin/yabootconfig [new file with mode: 0755]
ybin/ybin [new file with mode: 0755]

diff --git a/BUGS b/BUGS
new file mode 100644 (file)
index 0000000..b33068d
--- /dev/null
+++ b/BUGS
@@ -0,0 +1 @@
+Bugs? what bugs? if you find one let me know. send to: erbenson@alaska.net
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..d60c31a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+                   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.
index 50a963859dc109eef1d0b6b3201426318d78780f..f096b152f0e6a384e2974fd0a7c02feaafec3216 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,3 +2,144 @@
 # tag: automatic-ChangeLog--erbenson@alaska.net--public/yaboot--devel--1.3
 #
 
 # 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
+
+
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..87d8a3b
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,23 @@
+
+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'.
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..94ce349
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,199 @@
+## 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
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..01bcd36
--- /dev/null
+++ b/README
@@ -0,0 +1,421 @@
+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.
+
+===========================================================================
diff --git a/README.man.patch b/README.man.patch
new file mode 100644 (file)
index 0000000..445ae22
--- /dev/null
@@ -0,0 +1,4 @@
+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.
diff --git a/THANKS b/THANKS
new file mode 100644 (file)
index 0000000..630a169
--- /dev/null
+++ b/THANKS
@@ -0,0 +1,17 @@
+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!
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..c2d7f5a
--- /dev/null
+++ b/TODO
@@ -0,0 +1,13 @@
+
+* 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
diff --git a/changelog b/changelog
new file mode 100644 (file)
index 0000000..7eb52a6
--- /dev/null
+++ b/changelog
@@ -0,0 +1,621 @@
+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:
diff --git a/doc/README.ofboot b/doc/README.ofboot
new file mode 100644 (file)
index 0000000..5d7bb33
--- /dev/null
@@ -0,0 +1,47 @@
+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.
diff --git a/doc/README.ofpath b/doc/README.ofpath
new file mode 100644 (file)
index 0000000..2d5b9f8
--- /dev/null
@@ -0,0 +1,25 @@
+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. 
diff --git a/doc/README.rs6000 b/doc/README.rs6000
new file mode 100644 (file)
index 0000000..67dd904
--- /dev/null
@@ -0,0 +1,80 @@
+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
+
diff --git a/doc/examples/README.dualboot.chrp b/doc/examples/README.dualboot.chrp
new file mode 100644 (file)
index 0000000..a49d39b
--- /dev/null
@@ -0,0 +1,26 @@
+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.
diff --git a/doc/examples/README.mbicons b/doc/examples/README.mbicons
new file mode 100644 (file)
index 0000000..677373f
--- /dev/null
@@ -0,0 +1,9 @@
+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.
diff --git a/doc/examples/README.simpleboot.chrp b/doc/examples/README.simpleboot.chrp
new file mode 100644 (file)
index 0000000..3413c71
--- /dev/null
@@ -0,0 +1,37 @@
+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!
diff --git a/doc/examples/dualboot.chrp b/doc/examples/dualboot.chrp
new file mode 100644 (file)
index 0000000..3cfbb23
--- /dev/null
@@ -0,0 +1,68 @@
+<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>
diff --git a/doc/examples/large-penguin.mbicon b/doc/examples/large-penguin.mbicon
new file mode 100644 (file)
index 0000000..754493a
--- /dev/null
@@ -0,0 +1,259 @@
+<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>
diff --git a/doc/examples/simpleboot.chrp b/doc/examples/simpleboot.chrp
new file mode 100644 (file)
index 0000000..af176e8
--- /dev/null
@@ -0,0 +1,62 @@
+<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>
diff --git a/doc/examples/yaboot.conf.multi-boot b/doc/examples/yaboot.conf.multi-boot
new file mode 100644 (file)
index 0000000..0bbeaeb
--- /dev/null
@@ -0,0 +1,112 @@
+## 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
diff --git a/doc/examples/yaboot.conf.rs6k b/doc/examples/yaboot.conf.rs6k
new file mode 100644 (file)
index 0000000..b9f9a44
--- /dev/null
@@ -0,0 +1,72 @@
+## 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
diff --git a/etc/yaboot.conf b/etc/yaboot.conf
new file mode 100644 (file)
index 0000000..5d19f94
--- /dev/null
@@ -0,0 +1,81 @@
+## 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
diff --git a/first/ofboot b/first/ofboot
new file mode 100644 (file)
index 0000000..fc6b08a
--- /dev/null
@@ -0,0 +1,345 @@
+#%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 &lt;
+until
+drop
+\"  \"(0d 0a)\" .printf $DEFAULTOS
+</BOOT-SCRIPT>
+$OFBOOTICON
+</CHRP-BOOT>\n" > "$TMPBOOT"
+
+echo "$TMPBOOT"
diff --git a/include/asm/elf.h b/include/asm/elf.h
new file mode 100644 (file)
index 0000000..fc3c015
--- /dev/null
@@ -0,0 +1,57 @@
+#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
diff --git a/include/asm/ppc_asm.tmpl b/include/asm/ppc_asm.tmpl
new file mode 100644 (file)
index 0000000..e3004c8
--- /dev/null
@@ -0,0 +1,66 @@
+/* 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
diff --git a/include/asm/processor.h b/include/asm/processor.h
new file mode 100644 (file)
index 0000000..902facc
--- /dev/null
@@ -0,0 +1,142 @@
+#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 */
diff --git a/include/bootinfo.h b/include/bootinfo.h
new file mode 100644 (file)
index 0000000..b5b5a04
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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 */
+
diff --git a/include/byteorder.h b/include/byteorder.h
new file mode 100644 (file)
index 0000000..2403afe
--- /dev/null
@@ -0,0 +1,13 @@
+#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_ */
diff --git a/include/cfg.h b/include/cfg.h
new file mode 100644 (file)
index 0000000..2cbdaf3
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+    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
diff --git a/include/cmdline.h b/include/cmdline.h
new file mode 100644 (file)
index 0000000..e2baa61
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+    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
diff --git a/include/ctype.h b/include/ctype.h
new file mode 100644 (file)
index 0000000..afa3639
--- /dev/null
@@ -0,0 +1,54 @@
+#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
diff --git a/include/et/com_err.c b/include/et/com_err.c
new file mode 100644 (file)
index 0000000..81a70cf
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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;
+}
diff --git a/include/et/com_err.h b/include/et/com_err.h
new file mode 100644 (file)
index 0000000..f28dce8
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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) */
diff --git a/include/ext2fs/bitops.h b/include/ext2fs/bitops.h
new file mode 100644 (file)
index 0000000..0361d9b
--- /dev/null
@@ -0,0 +1,603 @@
+/*
+ * 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
+
diff --git a/include/ext2fs/ext2_err.h b/include/ext2fs/ext2_err.h
new file mode 100644 (file)
index 0000000..e986a5c
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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
diff --git a/include/ext2fs/ext2_io.h b/include/ext2fs/ext2_io.h
new file mode 100644 (file)
index 0000000..9568866
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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 */
+       
diff --git a/include/ext2fs/ext2fs.h b/include/ext2fs/ext2fs.h
new file mode 100644 (file)
index 0000000..474c947
--- /dev/null
@@ -0,0 +1,989 @@
+/*
+ * 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 */
diff --git a/include/fdisk-part.h b/include/fdisk-part.h
new file mode 100644 (file)
index 0000000..382df2d
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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 */
+};
diff --git a/include/file.h b/include/file.h
new file mode 100644 (file)
index 0000000..c68d84f
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+    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
diff --git a/include/fs.h b/include/fs.h
new file mode 100644 (file)
index 0000000..3ec5928
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+    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
diff --git a/include/gui.h b/include/gui.h
new file mode 100644 (file)
index 0000000..c1aaec6
--- /dev/null
@@ -0,0 +1,3 @@
+extern void fxDisplaySplash(struct boot_fspec_t *filespec);
+int fxReadImage(struct boot_file_t *file, unsigned int filesize, void *base);
+
diff --git a/include/linux/elf.h b/include/linux/elf.h
new file mode 100644 (file)
index 0000000..81d6f10
--- /dev/null
@@ -0,0 +1,607 @@
+#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 */
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
new file mode 100644 (file)
index 0000000..fc3d48c
--- /dev/null
@@ -0,0 +1,624 @@
+/*
+ *  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 */
diff --git a/include/linux/iso_fs.h b/include/linux/iso_fs.h
new file mode 100644 (file)
index 0000000..5e4610a
--- /dev/null
@@ -0,0 +1,177 @@
+
+#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
diff --git a/include/linux/stat.h b/include/linux/stat.h
new file mode 100644 (file)
index 0000000..0cb11ee
--- /dev/null
@@ -0,0 +1,45 @@
+#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
diff --git a/include/linux/types.h b/include/linux/types.h
new file mode 100644 (file)
index 0000000..be3a85b
--- /dev/null
@@ -0,0 +1 @@
+#include "../types.h"
\ No newline at end of file
diff --git a/include/mac-part.h b/include/mac-part.h
new file mode 100644 (file)
index 0000000..428f623
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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 */
+};
diff --git a/include/md5.h b/include/md5.h
new file mode 100644 (file)
index 0000000..c1dbd06
--- /dev/null
@@ -0,0 +1,30 @@
+/* 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)
diff --git a/include/partition.h b/include/partition.h
new file mode 100644 (file)
index 0000000..244227f
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+    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
diff --git a/include/prom.h b/include/prom.h
new file mode 100644 (file)
index 0000000..b217be4
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+    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
diff --git a/include/reiserfs/reiserfs.h b/include/reiserfs/reiserfs.h
new file mode 100644 (file)
index 0000000..2e27a27
--- /dev/null
@@ -0,0 +1,405 @@
+#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_ */
diff --git a/include/setjm2.h b/include/setjm2.h
new file mode 100644 (file)
index 0000000..73d06c9
--- /dev/null
@@ -0,0 +1,101 @@
+/* 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  */
diff --git a/include/setjmp.h b/include/setjmp.h
new file mode 100644 (file)
index 0000000..e31d6b3
--- /dev/null
@@ -0,0 +1,39 @@
+/* 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
diff --git a/include/stdlib.h b/include/stdlib.h
new file mode 100644 (file)
index 0000000..0b5e99a
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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
diff --git a/include/string.h b/include/string.h
new file mode 100644 (file)
index 0000000..6d65773
--- /dev/null
@@ -0,0 +1,35 @@
+#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_ */
diff --git a/include/swab.h b/include/swab.h
new file mode 100644 (file)
index 0000000..40c7c8a
--- /dev/null
@@ -0,0 +1,25 @@
+#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_ */
diff --git a/include/types.h b/include/types.h
new file mode 100644 (file)
index 0000000..1a1f403
--- /dev/null
@@ -0,0 +1,60 @@
+#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
diff --git a/include/video.h b/include/video.h
new file mode 100644 (file)
index 0000000..c5f61b8
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __VIDEO_H__
+#define __VIDEO_H__
+
+
+
+#endif
\ No newline at end of file
diff --git a/include/yaboot.h b/include/yaboot.h
new file mode 100644 (file)
index 0000000..d7a9277
--- /dev/null
@@ -0,0 +1,20 @@
+#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
diff --git a/lib/ctype.c b/lib/ctype.c
new file mode 100644 (file)
index 0000000..e028af4
--- /dev/null
@@ -0,0 +1,46 @@
+#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;
+    }
+}
+
diff --git a/lib/libext2fs.a b/lib/libext2fs.a
new file mode 100644 (file)
index 0000000..a6889b6
Binary files /dev/null and b/lib/libext2fs.a differ
diff --git a/lib/malloc.c b/lib/malloc.c
new file mode 100644 (file)
index 0000000..45f1409
--- /dev/null
@@ -0,0 +1,110 @@
+/* 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;
+}
diff --git a/lib/nosys.c b/lib/nosys.c
new file mode 100644 (file)
index 0000000..5208008
--- /dev/null
@@ -0,0 +1,5 @@
+/* we got no time */
+long time()
+{
+    return 0;
+}
diff --git a/lib/string.S b/lib/string.S
new file mode 100644 (file)
index 0000000..6c6b9b2
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * 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
diff --git a/lib/strstr.c b/lib/strstr.c
new file mode 100644 (file)
index 0000000..fbe7cfb
--- /dev/null
@@ -0,0 +1,119 @@
+/* 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;
+}
diff --git a/lib/strtol.c b/lib/strtol.c
new file mode 100644 (file)
index 0000000..2a38f3a
--- /dev/null
@@ -0,0 +1,140 @@
+/* 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;
+}
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
new file mode 100644 (file)
index 0000000..fd9ad7b
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ *  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;
+}
diff --git a/man.patch b/man.patch
new file mode 100644 (file)
index 0000000..18c7f00
--- /dev/null
+++ b/man.patch
@@ -0,0 +1,132 @@
+diff -urN -X CVS man/mkofboot.8 man.deb/mkofboot.8
+--- man/mkofboot.8     Thu May 24 04:32:54 2001
++++ man.deb/mkofboot.8 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
diff --git a/man/bootstrap.8 b/man/bootstrap.8
new file mode 100644 (file)
index 0000000..3d0e3c3
--- /dev/null
@@ -0,0 +1,272 @@
+.\" 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).
diff --git a/man/mkofboot.8 b/man/mkofboot.8
new file mode 100644 (file)
index 0000000..09e2a48
--- /dev/null
@@ -0,0 +1,249 @@
+.\" 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).
diff --git a/man/ofpath.8 b/man/ofpath.8
new file mode 100644 (file)
index 0000000..b0c7894
--- /dev/null
@@ -0,0 +1,87 @@
+.\" 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).
diff --git a/man/yaboot.8 b/man/yaboot.8
new file mode 100644 (file)
index 0000000..f7126a4
--- /dev/null
@@ -0,0 +1,132 @@
+.\" 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).
diff --git a/man/yaboot.conf.5 b/man/yaboot.conf.5
new file mode 100644 (file)
index 0000000..0378739
--- /dev/null
@@ -0,0 +1,635 @@
+.\" 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).
diff --git a/man/yabootconfig.8 b/man/yabootconfig.8
new file mode 100644 (file)
index 0000000..8d169ee
--- /dev/null
@@ -0,0 +1,137 @@
+.\" 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),
diff --git a/man/ybin.8 b/man/ybin.8
new file mode 100644 (file)
index 0000000..7489f94
--- /dev/null
@@ -0,0 +1,262 @@
+.\" 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),
diff --git a/second/cache.S b/second/cache.S
new file mode 100644 (file)
index 0000000..de445d6
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  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
diff --git a/second/cfg.c b/second/cfg.c
new file mode 100644 (file)
index 0000000..ee90116
--- /dev/null
@@ -0,0 +1,457 @@
+/* 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;
+}
diff --git a/second/cmdline.c b/second/cmdline.c
new file mode 100644 (file)
index 0000000..bf73024
--- /dev/null
@@ -0,0 +1,82 @@
+/* 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;
+}
diff --git a/second/crt0.S b/second/crt0.S
new file mode 100644 (file)
index 0000000..f06fe54
--- /dev/null
@@ -0,0 +1,32 @@
+#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
diff --git a/second/file.c b/second/file.c
new file mode 100644 (file)
index 0000000..726f313
--- /dev/null
@@ -0,0 +1,259 @@
+/* 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;
+}
diff --git a/second/fs.c b/second/fs.c
new file mode 100644 (file)
index 0000000..b5ba2ca
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+    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;
+}
diff --git a/second/fs_ext2.c b/second/fs_ext2.c
new file mode 100644 (file)
index 0000000..e2a5070
--- /dev/null
@@ -0,0 +1,604 @@
+/* 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;
+}
+
diff --git a/second/fs_iso.c b/second/fs_iso.c
new file mode 100644 (file)
index 0000000..9f52a3d
--- /dev/null
@@ -0,0 +1,77 @@
+/* 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;
+}
diff --git a/second/fs_of.c b/second/fs_of.c
new file mode 100644 (file)
index 0000000..abb006b
--- /dev/null
@@ -0,0 +1,241 @@
+/* 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;
+}
+
diff --git a/second/fs_reiserfs.c b/second/fs_reiserfs.c
new file mode 100644 (file)
index 0000000..f28680f
--- /dev/null
@@ -0,0 +1,1025 @@
+/* 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;
+}
diff --git a/second/gui/colormap.c b/second/gui/colormap.c
new file mode 100644 (file)
index 0000000..1317d46
--- /dev/null
@@ -0,0 +1,108 @@
+/* 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,
+};
diff --git a/second/gui/effects.c b/second/gui/effects.c
new file mode 100644 (file)
index 0000000..afcd374
--- /dev/null
@@ -0,0 +1,95 @@
+/* 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);
+}
diff --git a/second/gui/pcx.c b/second/gui/pcx.c
new file mode 100644 (file)
index 0000000..0509777
--- /dev/null
@@ -0,0 +1,31 @@
+/* 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);
+  }
+}
diff --git a/second/gui/video.c b/second/gui/video.c
new file mode 100644 (file)
index 0000000..b3bd572
--- /dev/null
@@ -0,0 +1,147 @@
+#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 );
+}
diff --git a/second/iso_util.c b/second/iso_util.c
new file mode 100644 (file)
index 0000000..b8fca04
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  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));
+}
+
diff --git a/second/md5.c b/second/md5.c
new file mode 100644 (file)
index 0000000..3b67209
--- /dev/null
@@ -0,0 +1,380 @@
+/* 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
diff --git a/second/partition.c b/second/partition.c
new file mode 100644 (file)
index 0000000..aa04c86
--- /dev/null
@@ -0,0 +1,284 @@
+/* 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;
+}
+
+
diff --git a/second/prom.c b/second/prom.c
new file mode 100644 (file)
index 0000000..153020d
--- /dev/null
@@ -0,0 +1,559 @@
+/*
+    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);
+}
+
diff --git a/second/setjmp.S b/second/setjmp.S
new file mode 100644 (file)
index 0000000..6ec41a2
--- /dev/null
@@ -0,0 +1,56 @@
+       .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
diff --git a/second/yaboot.c b/second/yaboot.c
new file mode 100644 (file)
index 0000000..5925d07
--- /dev/null
@@ -0,0 +1,1465 @@
+/* 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, &params->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, &params->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, &params->kernel.file,
+       &params->kernel.part);
+    if (validate_fspec(&params->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,
+               &params->rd.file, &params->rd.part);
+           validate_fspec(&params->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,
+               &params->sysmap.file, &params->sysmap.part);
+           validate_fspec(&params->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,
+               &params->splash.file, &params->splash.part);
+           validate_fspec(&params->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(&params))
+           return;
+       if (!params.kernel.file)
+           continue;
+       
+#ifdef CONFIG_SPLASH_SCREEN
+       if (params.splash.file)
+               fxDisplaySplash(&params.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(&params.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(&params.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(&params.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;
+}
diff --git a/util/addnote.c b/util/addnote.c
new file mode 100644 (file)
index 0000000..4088c32
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * 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);
+}
diff --git a/util/elfextract.c b/util/elfextract.c
new file mode 100644 (file)
index 0000000..a153017
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * 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);
+}
diff --git a/ybin/mkofboot b/ybin/mkofboot
new file mode 120000 (symlink)
index 0000000..63c46fd
--- /dev/null
@@ -0,0 +1 @@
+ybin
\ No newline at end of file
diff --git a/ybin/ofpath b/ybin/ofpath
new file mode 100755 (executable)
index 0000000..80d811d
--- /dev/null
@@ -0,0 +1,831 @@
+#! /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
diff --git a/ybin/yabootconfig b/ybin/yabootconfig
new file mode 100755 (executable)
index 0000000..e94c4ef
--- /dev/null
@@ -0,0 +1,635 @@
+#! /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
diff --git a/ybin/ybin b/ybin/ybin
new file mode 100755 (executable)
index 0000000..591e04e
--- /dev/null
+++ b/ybin/ybin
@@ -0,0 +1,1677 @@
+#! /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